OTX-Runtime for DotNet  
Integration

One design goal of the OTX-Runtime was the integrability into arbitrary target systems. Because of the different target systems can have complete different environments, the OTX-Runtime is open at almost each useful layer, see picture below.

The user can exchange the:

  1. Custom Implementations
    • Screen implementation (HMI extension)
    • Implementation for OTX context and state variables
    • Implementation for access to arbitrary device drivers (Measure extension)
    • Implementation for access to arbitrary libraries (ExternalServiceProvider extension)
    • Logging implementation (Logging extension)
    • Implementation for internalization (i18n extension)
  2. API technology (C++, DotNet or Java)
  3. Behavior of diagnostic communication (Diagnostic Command Processor)
  4. Diagnostic Runtime System implementation (MVCI-Server)

Note: For each of the above listed functions a default implementation is delivered.

Note: If the above listed functions are not sufficient, the user can write and integrate own implementations by himself.

Custom Implementations

Usually the OTX-Runtime implements the runtime behavior of all actions and terms of the OTX extensions. This behavior cannot be changed. However, there are use cases in which the runtime behavior has to be adapted to specific environments without changing the OTX test logic. For example the technology of an HMI screen inside a production environment is completely different to a screen inside an after sales tester or inside the car. The so called custom implementations closes this gap. A custom implementation is an implementation of a certain OTX extension which can be changed by the user. The table below lists all OTX extensions with custom implementations. For each of this implementation the OTX-Runtime API provides an interface. The user can implement this interface by its own implementation.

For most custom implementations a so called default implementation will be delivered.

OTX Extension Custom Interface Default Implementation Descriptions
CommonDialogs ICommonDialogsImplementation Inside OTX-Runtime System dialogs used
ContextVariable IContextVariableImplementation ContextVariableImplementation Own DotNet process with OTX-Mapping
ExternalServiceProvider IExternalServiceProviderImplementation ExternalServiceProviderImplementation Own DotNet process with OTX-Mapping
HMI (Basic Screens) IBasicScreenImplementation BasicScreenImplementation, ConfirmDialog also inside OTX-Runtime ConfirmDialog uses system message box
HMI (Custom Screens) ICustomScreenImplementation CustomScreenImplementation Own DotNet process with OTX-Mapping
i18n Ii18nImplementation Inside OTX-Runtime
Logging ILoggingImplementation Inside OTX-Runtime
Measure IMeasureImplementation MeasureImplementation Own DotNet process with OTX-Mapping
SQL ISqlImplementation SqlImplementation
StateVariable IStateVariableImplementation StateVariableImplementation Own DotNet process with OTX-Mapping
TestResultHandling ITestResultHandlingImplementation TestResultHandlingImplementation

Note: If the default implementation is not inside the OTX-Runtime and the link to the implementation does not work, see table above, the default implementation is currently not available for the related technology (C++, DotNet or Java).

Usage of Default Custom Implementations

If the user wants to use the delivered default implementation and the default implementation is inside the OTX-Runtime, nothing have to do. But if needed, it is possible to override this default implementation by implementing the related interface, see ICustomScreenImplementation in the Code Examples.

If the default implementation is outside the OTX-Runtime (inside a separate file, see Installation), the user must bind this implementation via the SetCustomImplementation method to the RuntimeManager, see Code Examples. Custom implementations may have some settings which should be set before.

Note: The often used ConfirmDialog has a default implementation inside and outside the OTX-Runtime. So that a user does not need to bind a custom implementation for trivial OTX sequences.

Usage of Own Custom Implementations

To implement own implementations of the listed OTX extensions only the related interface have to be implemented by the user, see Code Examples. This implementation must be bound via the SetCustomImplementation method to the RuntimeManager, see Code Examples.

Note: An own implementation can throw exceptions, e.g. if a screen cannot be opened. These exceptions will be forwarded to the OTX-Runtime and will throw there a related OTX exception, e.g. an implementation which implements the ICustomScreenImplementation interface will throw an OTX ScreenException of the HMI extension.

Note: Synchronous processing! While a custom implementation which implements an custom interface is processing a method call, the OTX runtime is blocked. It waits until the custom implementation has finished processing before resuming execution.

Note: The support of the OTX-Mapping in own custom implementations is recommended!

Code Examples

The following simplified pseudo code shows how a ICustomScreenImplementation can be implemented for a certain screen technology.

// Pseudo-Code example to implement custom screens
// ===============================================
// Please note that the exact syntax of C++, DotNet and Java is different!
public class CustomScreenImplementation : ICustomScreenImplementation
{
private IRuntimeSettings settings = null;
private static Dictionary<string, CustomScreen> screensCache = new Dictionary<string, CustomScreen>();
public IRuntimeSettings Settings
{
set => this.settings = value;
get => this.settings;
}
public CustomScreenImplementation()
{
}
public void CloseScreen(IScreenHandle screen)
{
if (screensCache != null && screensCache.ContainsKey(screen.ScreenId))
{
screensCache[screen.ScreenId].CloseScreen();
}
}
public void HighlightScreen(IScreenHandle screen)
{
if (screensCache != null && screensCache.ContainsKey(screen.ScreenId))
{
screensCache[screen.ScreenId].HighLightScreen();
}
}
public bool OpenScreen(IScreenHandle screen, bool modal, List<IScreenParameter> parameters)
{
CustomScreen customScreen;
if (settings != null && !string.IsNullOrWhiteSpace(screen.MappingName))
{
// ToDo: Manage OTX-Mapping
}
try
{
customScreen = new CustomScreen(screen, parameters);
customScreen.FormClosed += new FormClosedEventHandler((sender, e) => CustomScreen_Closed(sender, e, screen));
if (!screensCache.ContainsKey(screen.ScreenId))
{
screensCache.Add(screen.ScreenId, customScreen);
}
customScreen.OpenScreen(modal);
}
catch (Exception ex)
{
// Throw a ScreenException in OTX
throw new Exception("Screen cannot be opened", ex);
}
return customScreen.IsOpened;
}
private void CustomScreen_Closed(object sender, System.Windows.Forms.FormClosedEventArgs e, IScreenHandle screen)
{
screen.RaiseScreenClosedEvent();
if (screensCache != null && screensCache.ContainsKey(screen.ScreenId))
{
screensCache.Remove(screen.ScreenId);
}
}
public bool ScreenIsOpen(IScreenHandle screen)
{
if (screensCache != null && screensCache.ContainsKey(screen.ScreenId))
{
return screensCache[screen.ScreenId].Visible;
}
return false;
}
public void UpdateScreenParameterValues(IScreenHandle screen, List<string> parameterNames, object value)
{
if (screensCache.ContainsKey(screen.ScreenId) && screensCache[screen.ScreenId] != null)
{
screensCache[screen.ScreenId].UpdateScreenParameterValues(parameterNames, value);
}
}
}

The following pseudo code shows how the delivered custom implementations can be used.

// Pseudo-Code example to use custom implementations
// =================================================
// Please note that the exact syntax of C++, DotNet and Java is different!
void main()
{
// ...
// 1. Create custom implementations
CustomScreenImplementation customScreenImplementation = new CustomScreenImplementation();
// 2. Set custom specific properties, e.g. the HWND of the parent window
customScreenImplementation.HmiScreenHandle = hwnd;
// 3. Bind custom implementations to RuntimeManager
runtimeManager.SetCustomImplementation(customScreenImplementation);
// ...
}

API technology

The OTX-Runtime is written in native C++ and can be compiled for arbitrary systems at Windows, Linux and for embedded systems. To integrate the OTX-Runtime in a certain target system, APIs for C++, DotNet and Java are delivered, see Installation.

OTX-Runtime API for C++ OTX-Runtime API for DotNet OTX-Runtime API for Java

Diagnostic Command Processor

The exchangeable command processor is part of the OTX-DiagManager API. A default implementation of the command processor will be delivered together with the OTX-DiagManager API, see Binary Files for DiagManager. Each action and term of the related OTX extensions, see above will be transported via so called commands from the OtxDiagApi of the DiagManager to the diagnostic runtime system via the command processor. The command processor sequences and optimizes commands for access to the diagnostic runtime system. The command processor manages the interface handling, the lifetime of diagnostic runtime objects and target system specific functions.

The example above shows, how the command processor can be exchanged.

Note: If the user wants to integrate its own diagnostic behavior by himself please see Own Command Processor.

Diagnostic Runtime System

The diagnostic runtime system is part of the OTX-DiagManager API. All default implementations for different diagnostic runtime systems will be delivered together with the OTX-DiagManager API, see Binary Files for DiagManager. To support a certain diagnostic runtime system each action and term of the following OTX extensions (in alphabetical order) will be mapped to an appropriate function of the diagnostic runtime system.

Note: An diagnostic runtime systems which is compliant to ISO 22900-3 (MVCI-Server) is recommended, but also proprietary diagnostic runtime systems can be used.

Note: A diagnostic runtime systems must not support all extensions, but the user have to ensure that missing extensions shall not used inside the OTX sequence. Inside the OTX Development Environment not supported extensions can be hidden.

The following diagnostic runtime systems will be supported:

Name Version Class ISO 22900-3 Contained in File Description
VW-MCD 9.0 to 17.0 VwMcdDiagRuntimeSystem Yes OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.dll  Implements the VW-MCD version 9 to 17.00
VW-MCD 17.50 VwMcdDiagRuntimeSystem Yes OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd_VC142.dll  Implements the VW-MCD version 17.50 or later
VW-MCD (SP) 9.0 to 17.0 VwMcdSPDiagRuntimeSystem Yes OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd90SP.dll  Implements the VW-MCD with shared pointers version 9 to 17.00
VW-MCD (SP) 17.50 VwMcdSPDiagRuntimeSystem Yes OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdSP_VC142.dll  Implements the VW-MCD with shared pointers version 17.50 or later

Code Example

The following pseudo code shows how a diagnostic runtime systems must be created and assigned to the OTX-DiagManager API.

// Pseudo-Code example to create a DiagRuntimeSystem
// =================================================
// Please note that the exact syntax of C++, DotNet and Java is different!
//
// Add a reference to the binary of the DiagRuntimeSystem (e.g. "OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcd_VC142.dll"), see table above
//
void main()
{
// ...
// Creates an instance of the VW-MCD with the given project and vehicle name
DiagRuntimeSystem diagRuntimeSystem = new OpenTestSystem.Otx.DiagManager.DiagRuntimeSystem.VwMcdDiagRuntimeSystem("918S_1_23", "CAN");
// Creates an instance of the CommandProcessor and sets the diagnostic runtime system on it
CommandProcessor commandProcessor = new OpenTestSystem.Otx.DiagManager.CommandProcessor();
cmdProcessor.SetRuntimeSystem(diagRuntimeSystem);
// Creates the DiagManager server
ServerFactory serverFactory = new OpenTestSystem.Otx.DiagManager.Server.ServerFactory();
serverFactory.SocketPort = 8888;
OpenTestSystem.Otx.DiagManager.Server.Server server = serverFactory.Create(OpenTestSystem.Otx.DiagManager.Server.ServerType.Socket);
server.SetCommandProcessor(commandProcessor);
// Starts the DiagManager server listening at port 8888
server.Start();
// ...
}

Note: If the user wants to integrate its own proprietary diagnostic runtime systems by himself please see Own Diagnostic Runtime System.

OpenTestSystem.Otx.Runtime.Api.Custom
Namespace containing all interfaces for custom implementations
Definition: IBasicScreenImplementation.cs:7
OpenTestSystem.Otx
Namespace containing all objects which are standardized according to ISO 13209 (OTX)
OpenTestSystem.Otx.DiagManager
Namespace containing all objects for the communication to various, interchangeable diagnostic runtime...
OpenTestSystem.Otx.Runtime
Namespace containing all objects for browsing and execution of OTX procedures
Definition: ApiConstants.cs:5
OpenTestSystem.Otx.DiagManager.OtxDiagApi.DataTypes::OtxExceptionType::Exception
@ Exception
OpenTestSystem
Namespace containing all objects related to testing inside automotive industry
OpenTestSystem.Otx.Runtime.Api
Namespace containing the programming interface for browsing and execution of OTX procedures in own ap...
Definition: ApiConstants.cs:5