提交:初始化
This commit is contained in:
commit
70fca2d84c
67
App.config
Normal file
67
App.config
Normal file
@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
|
||||
<runtime>
|
||||
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Tecan.At.Dragonfly.Framework" publicKeyToken="2ecf6b23f06e7950" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.3.0.0" newVersion="2.3.0.0" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.4.1" newVersion="4.0.4.1" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Tecan.At.Dragonfly.Data.DomainObjects.Workspace" publicKeyToken="2ecf6b23f06e7950" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.4.12.0" newVersion="2.4.12.0" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Tecan.At.Dragonfly.Component.Shared" publicKeyToken="2ecf6b23f06e7950" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.3.0.0" newVersion="3.3.0.0" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Tecan.At.Dragonfly.Imaging.Data" publicKeyToken="2ecf6b23f06e7950" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.4.3.0" newVersion="2.4.3.0" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Tecan.At.Dragonfly.Component.Shared.Microplate" publicKeyToken="2ecf6b23f06e7950" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
<!--<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="Tecan.At.Dragonfly.Imaging" publicKeyToken="2ecf6b23f06e7950" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.1.5.0" newVersion="3.1.5.0" />
|
||||
|
||||
</dependentAssembly>-->
|
||||
|
||||
</assemblyBinding>
|
||||
|
||||
</runtime>
|
||||
</configuration>
|
35
AutomationInterface.SampleApp.sln
Normal file
35
AutomationInterface.SampleApp.sln
Normal file
@ -0,0 +1,35 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28307.1022
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleApp", "SampleApp.csproj", "{153C39DC-DB8A-4E8D-9503-A51F4BE96513}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{153C39DC-DB8A-4E8D-9503-A51F4BE96513}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{153C39DC-DB8A-4E8D-9503-A51F4BE96513}.Debug|x64.Build.0 = Debug|x64
|
||||
{153C39DC-DB8A-4E8D-9503-A51F4BE96513}.Release|x64.ActiveCfg = Release|x64
|
||||
{153C39DC-DB8A-4E8D-9503-A51F4BE96513}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {E41B27F9-49B0-48B3-B3DD-9DA06108CE7B}
|
||||
EndGlobalSection
|
||||
GlobalSection(TeamFoundationVersionControl) = preSolution
|
||||
SccNumberOfProjects = 1
|
||||
SccEnterpriseProvider = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
|
||||
SccTeamFoundationServer = http://tfsapp01.tecan.net:8080/tfs/at_dragonfly
|
||||
SccProjectUniqueName0 = SampleApp.csproj
|
||||
SccProjectName0 = .
|
||||
SccAuxPath0 = http://tfsapp01.tecan.net:8080/tfs/at_dragonfly
|
||||
SccLocalPath0 = .
|
||||
SccProvider0 = {4CA58AB2-18FA-4F8D-95D4-32DDF27D184C}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
94
AutomationInterfaceAccess.cs
Normal file
94
AutomationInterfaceAccess.cs
Normal file
@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Tecan.At.Dragonfly.AutomationInterface;
|
||||
using Tecan.At.Dragonfly.AutomationInterface.Data;
|
||||
using Tecan.At.Dragonfly.AutomationInterface.MethodModification;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
public static class AutomationInterfaceAccess
|
||||
{
|
||||
public static IReadOnlyCollection<IInstrument> GetInstruments()
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.InstrumentManagement.GetInstruments();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<string> GetMethods()
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.Queries.GetMethods().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetMethodXml(string methodName)
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.Queries.GetMethodXml(methodName);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckMethod(IInstrument selectedInstrument, string methodAsXml, string methodName, out IEnumerable<string> messages)
|
||||
{
|
||||
messages = null;
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.MethodExecution.CheckMethod(selectedInstrument, methodAsXml, methodName, out messages);
|
||||
}
|
||||
}
|
||||
|
||||
public static IMethodExecutionResult ExecuteMethod(IInstrument selectedInstrument, string methodAsXml, string methodName, bool isStacker)
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.MethodExecution.ExecuteMethod(selectedInstrument, methodAsXml, methodName, isStacker);
|
||||
}
|
||||
}
|
||||
|
||||
public static Task<IMethodExecutionResult> ExecuteMethodAsync(IInstrument selectedInstrument, string methodAsXml, string methodName, bool isStacker)
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.MethodExecution.ExecuteMethodAsync(selectedInstrument, methodAsXml, methodName, isStacker);
|
||||
}
|
||||
}
|
||||
|
||||
public static void CancelAsyncMethodExecution(IInstrument selectedInstrument)
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
ai.MethodExecution.Cancel(selectedInstrument);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ExportData(Guid workspaceId, Guid executionId)
|
||||
{
|
||||
using (var ai = AutomationInterfaceFactory.Build())
|
||||
{
|
||||
return ai.MethodExecution.GetResults(workspaceId, executionId);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ChangePlateLayout(string methodAsXml, int[] wellsToSelect)
|
||||
{
|
||||
using (var plateLayoutModifier = MethodModificationFactory.Build<IModifyPlateLayout>(ref methodAsXml))
|
||||
{
|
||||
var plateInfo = plateLayoutModifier.GetPlateInfo();
|
||||
for (uint wellIndex = 0; wellIndex < plateInfo.WellAmount; wellIndex++)
|
||||
{
|
||||
plateLayoutModifier.SelectWell(wellIndex, wellsToSelect.Any(x => x == wellIndex));
|
||||
}
|
||||
|
||||
methodAsXml = plateLayoutModifier.ApplyChangesToXmlString();
|
||||
}
|
||||
|
||||
return methodAsXml;
|
||||
}
|
||||
}
|
||||
}
|
63
CreateZipFile.ps1
Normal file
63
CreateZipFile.ps1
Normal file
@ -0,0 +1,63 @@
|
||||
try
|
||||
{
|
||||
# see https://stackoverflow.com/questions/9948517/how-to-stop-a-powershell-script-on-the-first-error
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
Add-Type -A System.IO.Compression.FileSystem
|
||||
|
||||
|
||||
# Write-Host ('OS Tmp Dir: ' + $env:TEMP )
|
||||
|
||||
# create tmo dir
|
||||
$tmpDir = $env:TEMP + [guid]::NewGuid()
|
||||
Write-Host ('Use tmp-dir: ' + $tmpDir)
|
||||
|
||||
New-Item -ItemType Directory -Force -Path $tmpDir
|
||||
|
||||
|
||||
# copy Sample App source code files to tmp dir
|
||||
Copy-Item $($PSScriptRoot + "\*.cs") -Destination $tmpDir
|
||||
Copy-Item $($PSScriptRoot + "\*.config") -Destination $tmpDir
|
||||
Copy-Item $($PSScriptRoot + "\*.csproj") -Destination $tmpDir
|
||||
Copy-Item $($PSScriptRoot + "\*.sln") -Destination $tmpDir
|
||||
Copy-Item $($PSScriptRoot + "\*.txt") -Destination $tmpDir
|
||||
Copy-Item $($PSScriptRoot + "\Properties") -Destination $tmpDir -Recurse
|
||||
|
||||
# copy Automation Interface docu to tmp dir
|
||||
# -> PDF is currently not included into ZIP file
|
||||
# $aiDocuFileName = Resolve-Path -Path $($PSScriptRoot + "\..\..\Production\Automation\AutomationInterface\Doc\AutomationInterfaceManual.pdf")
|
||||
# Write-Host ('aiDocuFileName : ' + $aiDocuFileName )
|
||||
# Copy-Item $aiDocuFileName -Destination $tmpDir
|
||||
|
||||
|
||||
# create zip file
|
||||
$zipFileName = $PSScriptRoot + "\SampleApp.zip"
|
||||
Write-Host ('zipFileName: ' + $zipFileName )
|
||||
|
||||
if (Test-Path $zipFileName)
|
||||
{
|
||||
Write-Host("Delete already available .zip file...")
|
||||
Remove-Item -Recurse -Force $zipFileName
|
||||
}
|
||||
|
||||
# ...and create it
|
||||
[IO.Compression.ZipFile]::CreateFromDirectory($tmpDir, $zipFileName)
|
||||
|
||||
# delete temp directory
|
||||
Write-Host ('Del tmp folder : ' + $tmpDir )
|
||||
Remove-Item -Recurse -Force $tmpDir
|
||||
|
||||
|
||||
Write-Host('')
|
||||
Write-Host('')
|
||||
Write-Host('##############################################################################')
|
||||
Write-Host('Successfully created Sample Application .zip file: ' + $zipFileName)
|
||||
Write-Host('##############################################################################')
|
||||
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error('ERROR: ' + $_.Exception)
|
||||
exit $LASTEXITCODE
|
||||
}
|
17
DemoAttribute.cs
Normal file
17
DemoAttribute.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class DemoAttribute : Attribute
|
||||
{
|
||||
public string Name { get; private set; }
|
||||
public char Key { get; private set; }
|
||||
|
||||
public DemoAttribute(string name, char key)
|
||||
{
|
||||
Name = name;
|
||||
Key = key;
|
||||
}
|
||||
}
|
||||
}
|
11
ExportDemo.cs
Normal file
11
ExportDemo.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
internal class ExportDemo
|
||||
{
|
||||
[Demo("exportData", 'a')]
|
||||
public static void Export(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
sampleApp.ExportData(sessionData);
|
||||
}
|
||||
}
|
||||
}
|
92
InputData.cs
Normal file
92
InputData.cs
Normal file
@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
public enum AutomationInterfaceActions
|
||||
{
|
||||
Undefined,
|
||||
GetInstrument,
|
||||
GetAllMethods,
|
||||
GetMethod,
|
||||
CheckMethod,
|
||||
ExecuteMethod,
|
||||
PlateOut,
|
||||
PlateIn,
|
||||
ExportData,
|
||||
ClearSession,
|
||||
StartWorkflow
|
||||
}
|
||||
|
||||
public class InputData
|
||||
{
|
||||
public AutomationInterfaceActions Action { get; private set; }
|
||||
public List<string> Parameter { get; } = new List<string>();
|
||||
|
||||
public bool Parse(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return false;
|
||||
|
||||
string[] parts = value.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
if (!GetAction(parts[0]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 1; i < parts.Length; i++)
|
||||
{
|
||||
Parameter.Add(parts[i]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool GetAction(string part)
|
||||
{
|
||||
if (!part.StartsWith("-"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (part.ToLower())
|
||||
{
|
||||
case "-getinstrument":
|
||||
Action = AutomationInterfaceActions.GetInstrument;
|
||||
break;
|
||||
case "-getallmethods":
|
||||
Action = AutomationInterfaceActions.GetAllMethods;
|
||||
break;
|
||||
case "-getmethod":
|
||||
Action = AutomationInterfaceActions.GetMethod;
|
||||
break;
|
||||
case "-checkmethod":
|
||||
Action = AutomationInterfaceActions.CheckMethod;
|
||||
break;
|
||||
case "-executemethod":
|
||||
Action = AutomationInterfaceActions.ExecuteMethod;
|
||||
break;
|
||||
case "-plateout":
|
||||
Action = AutomationInterfaceActions.PlateOut;
|
||||
break;
|
||||
case "-platein":
|
||||
Action = AutomationInterfaceActions.PlateIn;
|
||||
break;
|
||||
case "-exportdata":
|
||||
Action = AutomationInterfaceActions.ExportData;
|
||||
break;
|
||||
case "-clearsession":
|
||||
Action = AutomationInterfaceActions.ClearSession;
|
||||
break;
|
||||
case "-startworkflow":
|
||||
Action = AutomationInterfaceActions.StartWorkflow;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
60
InstrumentDemo.cs
Normal file
60
InstrumentDemo.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using Tecan.At.Dragonfly.AutomationInterface;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
internal class InstrumentDemo
|
||||
{
|
||||
[Demo("getInstrument <alias>", '1')]
|
||||
public static void GetInstrumentByAlias(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("Instrument alias? ");
|
||||
var aliasPart = Console.ReadLine();
|
||||
|
||||
sampleApp.GetInstrument(sessionData, aliasPart);
|
||||
|
||||
if (sessionData?.SelectedInstrument != null)
|
||||
{
|
||||
Console.WriteLine($"Selected instrument: {sessionData.SelectedInstrument.Alias ?? "<N.A.>"}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"No instrument available");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[Demo("plateOut", '8')]
|
||||
public static void PlateOut(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
using (AutomationInterfaceFactory.Build())
|
||||
{
|
||||
sessionData.SelectedInstrument.PlateOut();
|
||||
}
|
||||
}
|
||||
|
||||
[Demo("plateIn", '9')]
|
||||
public static void PlateIn(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
using (AutomationInterfaceFactory.Build())
|
||||
{
|
||||
sessionData.SelectedInstrument.PlateIn();
|
||||
}
|
||||
}
|
||||
|
||||
[Demo("getInstrumentState", 'f')]
|
||||
public static void GetState(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
using (AutomationInterfaceFactory.Build())
|
||||
{
|
||||
Console.WriteLine($"Instrument state is '{ sessionData.SelectedInstrument.State}'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
MethodExecutionDemo.cs
Normal file
61
MethodExecutionDemo.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
internal class MethodExecutionDemo
|
||||
{
|
||||
[Demo("checkMethod <methodFile>", '4')]
|
||||
public static void CheckMethod(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
IEnumerable<string> messages;
|
||||
sampleApp.CheckMethod(sessionData, methodFile, out messages);
|
||||
|
||||
Console.WriteLine(sessionData.MethodIsValid ? "valid" : "invalid");
|
||||
|
||||
foreach (var message in messages)
|
||||
{
|
||||
Console.WriteLine(message);
|
||||
}
|
||||
}
|
||||
|
||||
[Demo("executeMethod <methodFile>", '5')]
|
||||
public static void ExecuteMethod(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
sampleApp.ExecuteMethod(sessionData, methodFile, "AutomationInterfaceMethod", new int[] { });
|
||||
}
|
||||
|
||||
[Demo("executeMethodAsync <methodFile>", '6')]
|
||||
public static void ExecuteMethodAsync(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
sampleApp.ExecuteMethodAsync(sessionData, methodFile, "AutomationInterfaceMethod", new int[] { });
|
||||
}
|
||||
|
||||
[Demo("executeMethodAsyncAndCancel <methodFile>", '7')]
|
||||
public static void ExecuteMethodAsyncWithCancellation(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
sampleApp.ExecuteMethodAsyncAndCancel(sessionData, methodFile, "AutomationInterfaceMethod", new int[] { });
|
||||
}
|
||||
|
||||
[Demo("executeMethod (with stacker) <methodFile>", 'e')]
|
||||
public static void ExecuteMethodWithStacker(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
sampleApp.ExecuteMethod(sessionData, methodFile, "AutomationInterfaceMethod", new int[] { }, true);
|
||||
}
|
||||
}
|
||||
}
|
15
MiscDemo.cs
Normal file
15
MiscDemo.cs
Normal file
@ -0,0 +1,15 @@
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
internal class MiscDemo
|
||||
{
|
||||
[Demo("No Automation Interface scope available", 'd')]
|
||||
public static void Export(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
// inside method a scope is spanned
|
||||
sampleApp.GetInstrument(sessionData, string.Empty);
|
||||
|
||||
// no scope here
|
||||
sessionData.SelectedInstrument.PlateIn();
|
||||
}
|
||||
}
|
||||
}
|
119
Program.cs
Normal file
119
Program.cs
Normal file
@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Tecan.At.Dragonfly.AutomationInterface;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var commands = BuildCommands();
|
||||
|
||||
try
|
||||
{
|
||||
// Needed in your code
|
||||
AutomationInterfaceFactory.Start();
|
||||
|
||||
SessionData sessionData = null;
|
||||
var automationInterfaceAccess = new SampleApp();
|
||||
|
||||
var quitCommands = new[] { "q", "Q" };
|
||||
|
||||
while (true)
|
||||
{
|
||||
RenderMenu(commands);
|
||||
|
||||
var consoleInput = Console.ReadKey();
|
||||
Console.WriteLine();
|
||||
if (quitCommands.Any(x => x == consoleInput.KeyChar.ToString()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var command = '0';
|
||||
if (!char.TryParse(consoleInput.KeyChar.ToString(), out command))
|
||||
{
|
||||
Console.WriteLine($"'{consoleInput}' isn't a valid command key.");
|
||||
continue;
|
||||
}
|
||||
else if (commands.ContainsKey(command))
|
||||
{
|
||||
if (sessionData == null)
|
||||
{
|
||||
sessionData = new SessionData();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var theCommand = commands[command];
|
||||
|
||||
Console.WriteLine($"--- Execute command {theCommand.Item1}...");
|
||||
|
||||
theCommand.Item2.Invoke(automationInterfaceAccess, sessionData);
|
||||
|
||||
Console.WriteLine("--- done");
|
||||
}
|
||||
catch (TargetInvocationException e)
|
||||
{
|
||||
Console.WriteLine($"### Error: {e.InnerException.Message} ###");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(e.InnerException.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.ToString());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Unknown command '{command}'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Needed in your code
|
||||
AutomationInterfaceFactory.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private static void RenderMenu(Dictionary<char, Tuple<string, Action<SampleApp, SessionData>>> commands)
|
||||
{
|
||||
Console.WriteLine();
|
||||
commands.Keys.OrderBy(x => x).ToList().ForEach(c =>
|
||||
{
|
||||
var actCmd = commands[c];
|
||||
Console.WriteLine($"{c}. {actCmd.Item1}");
|
||||
});
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"Press q to exit.");
|
||||
Console.WriteLine();
|
||||
Console.Write("> ");
|
||||
}
|
||||
|
||||
private static Dictionary<char, Tuple<string, Action<SampleApp, SessionData>>> BuildCommands()
|
||||
{
|
||||
var methods = typeof(Program).Assembly.GetTypes()
|
||||
.SelectMany(t => t.GetMethods())
|
||||
.Where(m => m.GetCustomAttributes(typeof(DemoAttribute), false).Length > 0)
|
||||
.Select(x => new { Attribute = (DemoAttribute)x.GetCustomAttributes(typeof(DemoAttribute), false).Single(), Delegate = x })
|
||||
.ToArray();
|
||||
|
||||
var commands = new Dictionary<char, Tuple<string, Action<SampleApp, SessionData>>>(methods.Length);
|
||||
|
||||
foreach (var actDemo in methods)
|
||||
{
|
||||
commands.Add(actDemo.Attribute.Key, Tuple.Create<string, Action<SampleApp, SessionData>>(actDemo.Attribute.Name, (aia, sd) => { actDemo.Delegate.Invoke(null, new object[] { aia, sd }); }));
|
||||
}
|
||||
|
||||
Console.WriteLine($"Count: " + methods.Length);
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("AutomationInterface.IntegrationsTestsConsole")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("AutomationInterface.IntegrationsTestsConsole")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("153c39dc-db8a-4e8d-9503-a51f4be96513")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
41
QueryDemo.cs
Normal file
41
QueryDemo.cs
Normal file
@ -0,0 +1,41 @@
|
||||
using System;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
internal class QueryDemo
|
||||
{
|
||||
[Demo("getMethods", '2')]
|
||||
public static void GetAllMethods(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
sampleApp.GetMethods(sessionData);
|
||||
|
||||
foreach (var methodName in sessionData.AvailableMethods)
|
||||
{
|
||||
Console.WriteLine(methodName);
|
||||
}
|
||||
}
|
||||
|
||||
[Demo("getMethodXml<methodName> <targetFileName>", '3')]
|
||||
public static void GetMethodByNameAndTarget(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("method name? ");
|
||||
var methodName = Console.ReadLine();
|
||||
|
||||
var xmlString = sampleApp.GetMethodXml(methodName);
|
||||
|
||||
if (String.IsNullOrWhiteSpace(xmlString))
|
||||
{
|
||||
Console.WriteLine($"Method '{methodName}' not available.");
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"Loaded method '{methodName}'. Length: '{xmlString.Length}'.");
|
||||
|
||||
Console.Write("target file name? ");
|
||||
var targetFileName = Console.ReadLine();
|
||||
|
||||
// Console.WriteLine(xmlString);
|
||||
System.IO.File.WriteAllText(targetFileName, xmlString);
|
||||
}
|
||||
}
|
||||
}
|
21
README.txt
Normal file
21
README.txt
Normal file
@ -0,0 +1,21 @@
|
||||
Automation Interface Sample Application
|
||||
-----------------------------------------
|
||||
|
||||
To get the Sample Application running follow these steps:
|
||||
|
||||
1. Add a reference to your project to the file 'Tecan.At.Dragonfly.AutomationInterface.dll'.
|
||||
This file is located in the Clients folder usually under C:\Program Files\Tecan\SparkControl.
|
||||
|
||||
2. In Visual Studio project post build event add call to a powershell script.
|
||||
The script is called 'CopyAdditionalAutomationInterfaceFiles.ps1' and is located in the same folder as the 'AutomationInterface.dll'.
|
||||
|
||||
Example:
|
||||
powershell.exe <your path>\CopyAdditionalAutomationInterfaceFiles.ps1 $(TargetDir)
|
||||
|
||||
|
||||
Remark:
|
||||
It might be necessary that you add following call in your pre-build step:
|
||||
|
||||
powershell.exe Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force;
|
||||
|
||||
Try it first without this call!
|
185
SampleApp.cs
Normal file
185
SampleApp.cs
Normal file
@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
public class SampleApp
|
||||
{
|
||||
public void GetInstrument(SessionData sessionData, string aliasPart)
|
||||
{
|
||||
try
|
||||
{
|
||||
var availableInstruments = AutomationInterfaceAccess.GetInstruments();
|
||||
sessionData.SelectedInstrument = availableInstruments.FirstOrDefault(x => string.IsNullOrEmpty(aliasPart) || x.Alias.Contains(aliasPart));
|
||||
|
||||
if (sessionData.SelectedInstrument == null)
|
||||
{
|
||||
sessionData.SelectedInstrument = availableInstruments.FirstOrDefault(x => string.IsNullOrEmpty(aliasPart) || x.SerialNumber.Contains(aliasPart));
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetMethods(SessionData sessionData)
|
||||
{
|
||||
try
|
||||
{
|
||||
sessionData.AvailableMethods = AutomationInterfaceAccess.GetMethods();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetMethodXml(string methodName)
|
||||
{
|
||||
try
|
||||
{
|
||||
return AutomationInterfaceAccess.GetMethodXml(methodName);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckMethod(SessionData sessionData, string methodFile, out IEnumerable<string> messages)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
messages = null;
|
||||
try
|
||||
{
|
||||
string methodAsXml = System.IO.File.ReadAllText(methodFile);
|
||||
sessionData.MethodIsValid = AutomationInterfaceAccess.CheckMethod(sessionData.SelectedInstrument, methodAsXml, "MethodToCheck", out messages);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteMethod(SessionData sessionData, string methodFile, string methodName, int[] wellsToSelect, bool isStacker = false)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
try
|
||||
{
|
||||
string methodAsXml = System.IO.File.ReadAllText(methodFile);
|
||||
|
||||
if (wellsToSelect.Any())
|
||||
{
|
||||
methodAsXml = AutomationInterfaceAccess.ChangePlateLayout(methodAsXml, wellsToSelect);
|
||||
}
|
||||
|
||||
var result = AutomationInterfaceAccess.ExecuteMethod(sessionData.SelectedInstrument, methodAsXml, methodName, isStacker);
|
||||
if (result != null)
|
||||
{
|
||||
sessionData.WorkspaceId = result.WorkspaceId;
|
||||
sessionData.ExecutionId = result.ExecutionId;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Error executing method (checkMethod failed).");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteMethodAsync(SessionData sessionData, string methodFile, string methodName, int[] wellsToSelect, bool isStacker = false)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
try
|
||||
{
|
||||
string methodAsXml = System.IO.File.ReadAllText(methodFile);
|
||||
|
||||
if (wellsToSelect.Any())
|
||||
{
|
||||
methodAsXml = AutomationInterfaceAccess.ChangePlateLayout(methodAsXml, wellsToSelect);
|
||||
}
|
||||
|
||||
var task = AutomationInterfaceAccess.ExecuteMethodAsync(sessionData.SelectedInstrument, methodAsXml, methodName, isStacker);
|
||||
|
||||
Console.WriteLine($"Started method '{methodName}'...");
|
||||
while (task.Status == TaskStatus.Running)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
Console.Write(".");
|
||||
}
|
||||
|
||||
task.Wait();
|
||||
|
||||
if (task.Result != null)
|
||||
{
|
||||
sessionData.WorkspaceId = task.Result.WorkspaceId;
|
||||
sessionData.ExecutionId = task.Result.ExecutionId;
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine($"Executed method '{methodName}'. WorkspaceId: '{sessionData.WorkspaceId}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Error executing method (checkMethod failed).");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteMethodAsyncAndCancel(SessionData sessionData, string methodFile, string methodName, int[] wellsToSelect, bool isStacker = false)
|
||||
{
|
||||
sessionData.EnforceSetInstrument();
|
||||
|
||||
try
|
||||
{
|
||||
string methodAsXml = System.IO.File.ReadAllText(methodFile);
|
||||
|
||||
if (wellsToSelect.Any())
|
||||
{
|
||||
methodAsXml = AutomationInterfaceAccess.ChangePlateLayout(methodAsXml, wellsToSelect);
|
||||
}
|
||||
|
||||
var task = AutomationInterfaceAccess.ExecuteMethodAsync(sessionData.SelectedInstrument, methodAsXml, methodName, isStacker);
|
||||
Console.WriteLine($"Started method '{methodName}'...");
|
||||
|
||||
// method should be a rather complex method that it takes longer to execute as this thread is sleeping
|
||||
Thread.Sleep(5000);
|
||||
Console.WriteLine($"Cancel method execution.");
|
||||
|
||||
AutomationInterfaceAccess.CancelAsyncMethodExecution(sessionData.SelectedInstrument);
|
||||
Console.WriteLine($"Cancellation finished.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExportData(SessionData sessionData)
|
||||
{
|
||||
try
|
||||
{
|
||||
sessionData.ExportedDataFile = AutomationInterfaceAccess.ExportData(sessionData.WorkspaceId, sessionData.ExecutionId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
78
SampleApp.csproj
Normal file
78
SampleApp.csproj
Normal file
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{153C39DC-DB8A-4E8D-9503-A51F4BE96513}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>Tecan.At.AutomationInterface.SampleApp</RootNamespace>
|
||||
<AssemblyName>Tecan.At.AutomationInterface.SampleApp</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
<SccProjectName>SAK</SccProjectName>
|
||||
<SccLocalPath>SAK</SccLocalPath>
|
||||
<SccAuxPath>SAK</SccAuxPath>
|
||||
<SccProvider>SAK</SccProvider>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.ServiceProcess" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DemoAttribute.cs" />
|
||||
<Compile Include="ExportDemo.cs" />
|
||||
<Compile Include="InstrumentDemo.cs" />
|
||||
<Compile Include="MethodExecutionDemo.cs" />
|
||||
<Compile Include="MiscDemo.cs" />
|
||||
<Compile Include="QueryDemo.cs" />
|
||||
<Compile Include="SampleApp.cs" />
|
||||
<Compile Include="InputData.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SessionData.cs" />
|
||||
<Compile Include="AutomationInterfaceAccess.cs" />
|
||||
<Compile Include="WorkflowDemo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="README.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PreBuildEvent>powershell.exe Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Unrestricted -Force;</PreBuildEvent>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>powershell.exe <your path>\CopyAdditionalAutomationInterfaceFiles.ps1 $(TargetDir)</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
24
SessionData.cs
Normal file
24
SessionData.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Tecan.At.Dragonfly.AutomationInterface.Data;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
public class SessionData
|
||||
{
|
||||
public List<string> AvailableMethods { get; set; }
|
||||
public IInstrument SelectedInstrument { get; set; }
|
||||
public bool MethodIsValid { get; set; }
|
||||
public Guid WorkspaceId { get; set; }
|
||||
public Guid ExecutionId { get; set; }
|
||||
public string ExportedDataFile { get; set; }
|
||||
|
||||
public void EnforceSetInstrument()
|
||||
{
|
||||
if (SelectedInstrument == null)
|
||||
{
|
||||
throw new InvalidOperationException("Instrument is not set.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
61
WorkflowDemo.cs
Normal file
61
WorkflowDemo.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Tecan.At.AutomationInterface.SampleApp
|
||||
{
|
||||
internal class WorkflowDemo
|
||||
{
|
||||
[Demo("startWorkflow <methodFile>", 'b')]
|
||||
public static void Export(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("instrument alias? ");
|
||||
var instrumentAlias = Console.ReadLine();
|
||||
|
||||
Console.WriteLine("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
sessionData = new SessionData();
|
||||
sampleApp.GetInstrument(sessionData, instrumentAlias);
|
||||
sampleApp.ExecuteMethod(sessionData, methodFile, "AutomationInterfaceMethod", new int[] { });
|
||||
|
||||
sampleApp.ExportData(sessionData);
|
||||
|
||||
Console.WriteLine("Export: " + sessionData.ExportedDataFile);
|
||||
}
|
||||
|
||||
[Demo("select wells and execute <instrumentAlias> <methodFile> <wellIndices>", 'c')]
|
||||
public static void SelectWellsAndExport(SampleApp sampleApp, SessionData sessionData)
|
||||
{
|
||||
Console.Write("instrument alias? ");
|
||||
var instrumentAlias = Console.ReadLine();
|
||||
|
||||
Console.WriteLine("methodFile? ");
|
||||
var methodFile = Console.ReadLine();
|
||||
|
||||
Console.WriteLine("wells to select? Bsp: 2, 5, 32, ...");
|
||||
var wellsToSelectString = Console.ReadLine();
|
||||
|
||||
List<int> wellsToSelect = new List<int>();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(wellsToSelectString))
|
||||
{
|
||||
string[] intParts = wellsToSelectString.Split(new char[] { ',' });
|
||||
foreach (var intPart in intParts)
|
||||
{
|
||||
if (int.TryParse(intPart.Trim(), out int wellIndex))
|
||||
{
|
||||
wellsToSelect.Add(wellIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sessionData = new SessionData();
|
||||
sampleApp.GetInstrument(sessionData, instrumentAlias);
|
||||
sampleApp.ExecuteMethod(sessionData, methodFile, "AutomationInterfaceMethod", wellsToSelect.ToArray());
|
||||
|
||||
sampleApp.ExportData(sessionData);
|
||||
|
||||
Console.WriteLine("Export: " + sessionData.ExportedDataFile);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user