Sunteți pe pagina 1din 54

InTouch OMI SDK Help

Table of Contents

InTouch OMI Developer Guide 4


Legal and Contact Information 4
Legal Information 4-5
Contact Information 5
Introduction 5
About the SDK 5-6
InTouch OMI App Development Guidelines 6
Definitions and Conventions 6-7
Naming Conventions 7
Key Concepts 7
Screen Profiles 7
Layouts and Panes 7
Configurable Properties 7-8
Getting Started 8
Installation 8
Requirements 8-9
Getting Around the SDK 9-10
App Development Best Practices 10
InTouch OMI App Limitations and Restrictions 10-11
Assemblies (Component SDKs) 11-12
AppConfig SDK 12
Using the AppConfig SDK 12-13
EditorActivityViewModelBase Class 13-14
IEditor Interface 14
AppConfig Sample Class 14-16
CommonUtil SDK 16
RunTimeData SDK 16-17
Using the RunTimeData SDK 17-18
IRuntimeDataClient 18

1 InTouch OMI SDK Help


InTouch OMI SDK Help

Read and Write Status 18-20


Subscribe to References 20-21
Value, Timestamp, Quality and Status 21-25
Language Namespace 25-27
Using the Language Namespace 27-28
Interface Methods 28
Structures, Classes, and Enumerations 28-29
Graphic Control SDK 29
Using the GraphicControl SDK 29-30
Navigation Hierarchy API 30-33
Navigation SDK 33
Using the Navigation SDK 33-36
ViewApp SDK 36-37
Using the ViewApp SDK 37-38
ViewApp Attributes 38-41
Web Control SDK 41
Creating Your First InTouch OMI Application 41-42
Sample Applications 42
Create a New Project 42-43
Build the App UI 43-44
Build Your Business Logic 44-45
AppManifest.xml File 45-47
Global App Editor 47-48
App Editor Configuration 48-51
Troubleshooting 51
Add a Link to the Logger 51
Debug a Running App 51
Debugging an Initializing App 51-52
Redistributing Your Application 52
Import and Test Your App into the IDE 52-53

2 InTouch OMI SDK Help


InTouch OMI SDK Help
Export Your App 53
API Reference 53
54

3 InTouch OMI SDK Help


InTouch OMI SDK Help

InTouch OMI Developer Guide

Legal and Contact Information


This section provides copyright information, as well options for contacting technical support and other important
points of contact.
Copyrights
Contact Information

Copyrights
© 2017 Schneider Electric Software, LLC. All rights reserved.
No part of this documentation shall be reproduced, stored in a retrieval system, or transmitted by any means,
electronic, mechanical, photocopying, recording, or otherwise, without the prior written permission of Schneider
Electric Software, LLC. No liability is assumed with respect to the use of the information contained herein.
Although precaution has been taken in the preparation of this documentation, Schneider Electric Software, LLC
assumes no responsibility for errors or omissions. The information in this documentation is subject to change without
notice and does not represent a commitment on the part of Schneider Electric Software, LLC. The software described
in this documentation is furnished under a license agreement. This software may be used or copied only in
accordance with the terms of such license agreement.
ArchestrA, Avantis, DYNSIM, eDNA, EYESIM, Foxboro, Foxboro Evo, I/A Series, InBatch, InduSoft, InStep, IntelaTrac,
InTouch, PIPEPHASE, PRiSM, PRO/II, PROVISION, ROMeo, Schneider Electric, SIM4ME, SimCentral, SimSci, Skelta,
SmartGlance, Spiral Software, VISUAL FLARE, WindowMaker, WindowViewer, and Wonderware are trademarks of
Schneider Electric SE, its subsidiaries, and affiliated companies. An extensive listing of Schneider Electric Software,
LLC trademarks can be found at: http://software.schneider-electric.com/legal/trademarks/. All other brands may
be trademarks of their respective owners.

4 InTouch OMI SDK Help


InTouch OMI SDK Help
Schneider Electric Software, LLC
26561 Rancho Parkway South
Lake Forest, CA 92630 U.S.A.
(949) 727-3200
http://software.schneider-electric.com/

Contact Information
Wonderware Technical Support

Listing of regional and local country contacts: https://www.wonderware.com/contact/contact-support/


Technical support: http://softwaresupport.schneider-electric.com/
Priority email for Customer FIRST Members: custfirstsupport@wonderware.com
Email for customers without a support agreement: wwsupport@wonderware.com

Phone

Toll-Free North America and Latin America: 1-800-966-3371


Direct dial: 1-949-639-8500

Contact Schneider Electric Software Learning Services

Contact Software Learning Services for assistance regarding classes, schedule, offerings, frequently asked questions,
tuition, policies, and more.
Email: software.training@schneider-electric.com
Toll-Free U.S. and Canada: 1-866-998-7246
Direct: 1-949-639-8508
Fax: 1-949-639-1847

Introduction
This section provides background information about the InTouch OMI Software Developer Kit.
About the InTouch OMI SDK
InTouch OMI App Development Guidelines
Acronyms and Definitions

About the InTouch OMI SDK


The InTouch OMI SDK provides programmatic access to its component SDK assemblies and namespaces. Use the
methods and parameters that these provide to build your own InTouch OMI custom applications that can users can
configure for their ViewApps.
An InTouch OMI app, also called an ArchestrA app, is collection of one or more controls primarily developed with
Windows Presentation Foundation (WPF). Other technologies such as Windows Forms (WinForms) and HTML5, can also
be used. You can create your own custom apps, which can be imported via WPF interoperability. Apps should contain
at least one WPS FrameworkElement Class control (System.Windows.FrameworkElement).
Use the InTouch OMI Toolkit to build custom apps in Visual Studio that leverage WPF and the .NET Framework to

5 InTouch OMI SDK Help


InTouch OMI SDK Help
extend the functionality of your ViewApps with customized navigation, localization, and other content. The InTouch
OMI Toolkit uses the .NET application framework. It contains six component SDKs that each include a set of
overlapping APIs and libraries. The six component SDKs are:
Runtime Data SDK: The RunTime Data SDK exposes the API that lets you subscribe to, and read and write
from, single-value or multiple-value references.
ViewApp SDK: The ViewApp SDK exposes various methods that let you build controls and apps that can show
content in a pane.
AppConfig SDK: The Appconfig SDK exposes the API for developing and packaging custom editor popup
modules hosted within the System Platform IDE.
ProcessControls SDK: This SDK exposes reusable graphic and alarm adorner controls. You can use the
Navigation API, exposed by the Navigation SDK, to add these controls to navigation hierarchies.
Navigation SDK: The Navigation SDK exposes the API that lets you retrieve the underlying navigation model
and provides an easy way to build hierarchies to use in the apps that you develop.

Supported .NET Programming Languages

All classes, methods, properties, etc. that are exposed in the various SDKs are supported by the following .NET
programming languages:
C#
VB.Net
Visual C++ .Net
Managed Extensions for C++

InTouch OMI App Development Guidelines


The following types of properties are available for configuring WPF-based displays:
Public writeable CLR properties on the display that are not hidden using the browsable attribute.
Dependency Properties.
Nested Properties which satisfy the criteria of configurable properties.
Enum and Flag properties.
Any property that can be converted to or from string.
The following types of properties are NOT available for configuring WPF-displays:
Any property defined by the System.Windows.UIElement class.
Any property defined by the System.Windows.FrameworkElement class.
The Tooltip property is an exception to this and can be configured.
The following properties are defined by the System.Windows.Controls.Control class:
IsTabStop.
TabIndex.
Template.
Any property defined by the System.Windows.Controls.ContentControl class

Acronyms and Definitions


ACF: ArchestrA Control Framework. This is the app delivery framework for InTouch OMI.
API: Application Program Interface. A set of programming tools, including methods, classes, and properties, that you
can use to to build software applications.

6 InTouch OMI SDK Help


InTouch OMI SDK Help
ArchestrA: A distributed architecture developed by Wonderware for supervisory control and manufacturing
information systems. It is an open and extensible technology based on a distributed, object-based design.
Assembly: Microsoft defines assemblies as the building blocks of .NET Framework applications; they form the
fundamental unit of deployment, version control, reuse, activation scoping, and security permissions. An assembly is
a collection of types and resources that are built to work together and form a logical unit of functionality.
SDK: Software Developer Kit. A collection of APIs, sample apps, and documentation that lets software developers
build new applications. The InTouch OMI runs uses Microsoft Visual Studio as its development environment and
includes several APIs, along with sample apps and documentation.

Naming Conventions
SDK assembly and DLL names conform to the following pattern:
ArchestrA.Client.<SDK_Extension>.DLL, where SDK_Extension is the name of the SDK. For example, the name of the
DLL for the RunTimeData SDK is "ArchestrA.Client.RunTimeData.DLL."
Namespace names: Public namespace names conform to the same naming pattern as for SDK assembly and DLL
names, minus the "DLL" file extension. For example, the name of the namespace for the RunTimeData SDK is
"ArchestrA.Client.RunTimeData."
Non-public implementations of the the SDK namespace use the same name as the public namespace, but are
appended with "Internal." For example, "Archestra.Client.RunTimeData.Internal."

Key Concepts
This section defines some of the terms and technologies that you should be familiar with before using this SDK.
Screen Profiles
Layouts and Panes
Configurable Properties

Screen Profiles
Screen profiles define physical screen characteristics for ViewApps. Physical screen characteristics include resolution,
whether the screen is touch-enabled, and orientation (portrait or landscape). For additional information,
see WebHelp/index.htm#257577.

Layouts and Panes


Layouts are divided one or more rectangular areas called panes. Each pane can be individually sized, and
contains content to be displayed in a ViewApp at run time. When you build an app, you are building content that
can be added to a pane. For additional information, see InTouch OMI Help/Layouts.

Configurable Properties
An InTouch OMI app can contain two types of configurable properties:
CLR (.NET Framework) properties
Dependency properties
CLR properties can only be set at configuration (design) time, while dependency properties can be bound to any
attribute and can be set at run time. If a dependency property is changed at run time, the new value is propagated
to the attribute. Dependency properties are data-bindable at design time, and you can set the binding direction to in
(read), out (write), or both. To change the binding direction, click on the arrow to toggle the binding direction.

7 InTouch OMI SDK Help


InTouch OMI SDK Help

Data Bindable Properties


For dependency properties, you must specify the attribute to which you are binding the property, as well as the
direction of the binding (in (read only), out (write only) or both. The attribute naming convention is the same you
use, for example, when configuring an animation in the Graphic Editor. Note that the ViewApp Editor does not
provide syntax validation for attribute names, but the Logger will list any configuration errors. Binding is only
supported for the following basic data types.
System.Boolean
System.Byte
System.Char
System.Decimal
System.Double
System.Int16
System.Int32
System.Int64
System.SByte
System.Single
System.String
System.UInt16
System.Unit32
System.Unit64

Getting Started
Installation
Requirements
Getting Around the SDK
App Development Best Practices
InTouch OMI App Limitations and Restrictions

Installation
The InTouch OMI SDK and all component assemblies are installed automatically on the node when you select the IDE
component of Application Server for installation, using either the product-based or role-based option. Setup installs
the SDK binaries under the ArchestrA\Framework folder, in the following location:
64-bit systems: C:\Program Files (x86)\ArchestrA\Framework\AcfSdk\Libs
32-bit systems: C:\Program Files\ArchestrA\Framework\AcfSdk\Libs

Requirements
To use the InTouch OMI SDK, you must have the following software, operating system, and framework components
installed on your development system:
Visual Studio 2013 or higher
.NET Framework 4.5.2 or higher
Wonderware Application Server IDE (WSP 2017 Update 1)

8 InTouch OMI SDK Help


InTouch OMI SDK Help
An operating system supported by Wonderware System Platform 2017 Update 1 (see the WSP 2017 Update 1
Readme)

Getting Around the SDK


When you install the System Platform IDE, also known as the ArchestrA IDE, the SDK is added at the following default
location:
C:\Program Files (x86)\ArchestrA\Framework\AcfSdk
The SDK contains four subfolders:
Includes: Contains a logger (Logger.cs). You can add the logger as a reference, which is a shared class, to
assist in development and debugging. Use it to log messages, custom tracing, etc. See Add a Link to the
Logger for instructions about adding the logger to troubleshoot your app.
To add the logger:
1. In the Visual Studio Solution Explorer, select your app.
2. Right-click and select Add > Existing Item (or press ShiFt + Alt + A).
3. Navigate to the AcfSdk\Includes folder.
4. Select the Logger.cs file.
5. Click the down arrow on the Add button.
6. Click Add As Link.
Libs: Contains the assembly DLLs of the component SDKs. These are:
ArchestrA.ClientAppConfig.dll (assembly required for developing an app editor)
ArchestrA.Client.CommonUtil.dll (assembly that provides common content)
ArchestrA.Client.Navigation.dll
ArchestrA.Client.ProcessControls.dll
ArchestrA.Client.RuntimeData.dll
ArchestrA.Client.ViewApp.dll
ArchestrA.Client.WebControls.dll
Samples: Contains sample apps that you can extract code from for your own custom apps. A solution file
(SDKSamples.sln) is also provided to enable editing in Visual Studio 2013. The sample apps are also
available in the System Platform IDE, in the Graphic Toolbox (Default Content > 4. Apps > InTouch OMI
Apps).
ContentPresenterApp
HamburgerApp
NavBreadcrumb
NavTree
WebBrowserApp
SharedLibs: Contains third-party and open-source assemblies used for UI elements in the InTouch OMI Apps
that are included with Wonderware Application Server. These are:
ActiproSoftware.Docking.Wpf.dll
ActiproSoftware.Shared.Wpf.dll
MaterialDesignColors.dll
MaterialDesignThemes.Wpf.dll
Telerik.Windows.Controls.Data.dll
Telerik.Windows.Controls.dll
Telerik.Windows.Controls.Navigation.dll
Telerik.Windows.Data.dll
Telerik assemblies are supplied by a third-party, and controls from these assembles are used in bundled apps such as
the NavBreadcrumbControl and NavtreeControl. Actipro assemblies contain controls that are used for slide-in panes.
MaterialDesign assemblies are open source and are used to provide the look and feel of apps. You can choose

9 InTouch OMI SDK Help


InTouch OMI SDK Help
incorporate other open source or third-party assemblies as you write your apps.

App Development Best Practices


Assemblies
Use AnyCPU: All assemblies should be compiled as AnyCPU. The ACF codebase is designed to be neutral with regard
to how the application runs (as 32-bit or 64-bit). Note that the aaClient included with the current ArchestrA Client
Framework (ACF) is a 32-bit process, but a 64-bit version is available on request.
Do not import SDK DLLs with your App: When you import your App into a Galaxy, do not include the ACF SDK DLLs
with the App DLLs. ACF SDK DLLs are automatically placed in a common location and should not be included with
individual Apps.
Dependent files: Include all dependent DLLs and other files in the import folder and avoid external dependencies,
such as the GAC. ACF applications are intended to be self-contained and runnable on any machine that includes .Net
by x-copying the files. Other external dependencies should hosted by the ArchestrA Service Bus or in a network server
to eliminate the need for installation when applications are deployed to target nodes.

Controls
Standard Microsoft Designer Mode: Controls should support the Standard Microsoft Designer Mode for controls.
Control instances should be constructed in designer mode within ACF configuration tools when they are imported into
the Visualization Repository, and placed into the standard MSFT Designer Mode when edited. This mode should be
taken into account by the control developer to prevent unintended connections to data sources from occurring while
the control is being configured. The control developer must determine any required changes in behavior that are
needed if the host indicates that the control is running in the configuration environment.
IDisposable pattern: If necessary, implement the IDisposable pattern. When the IDisposable pattern is implemented,
the ACF host calls the Dispose() method on a control’s framework element whenever the control is closed.
Blocking operations: Do not block the UI thread for long operations. ACF supports one thread per top level window.
Other controls within the same window may be controlling live information and should not be frozen and made
unresponsive because of a blocking operation.
Cross-control communication: Each Screen Layout (top level window) in an ACF application has its own thread.
Since controls can only be accessed by callers running on their thread, all cross-control communication must be done
using the other control’s dispatcher object. This includes a control accessing its own properties when handling events
potentially fired from a different thread.
Use proper encapsulation (public vs private): Ensure that all types defined in App code are appropriately marked as
public or private. Only mark as public the controls and control properties that need to be used by consumers.
Filter public controls: Use the AppManifest.xml file to filter out any public controls that should not be visible in the
Galaxy Graphics Toolbox. This is useful when third-party DLLs that have public controls are included in the Apps
folder, but you do not want those controls to be visible in the Galaxy Graphics Toolbox. You can also usethe
AppManifest.xml file to filter out public properties on controls.
Specify default Values and categories: Controls should specify default values and categories for their public
browsable properties. This is standard for well-behaved controls edited via a property grid. It enables values to be
reset to their defaults and show in bold style if edited.
Follow standard exception handling patterns: Refer to the Microsoft guidelines at the following URL:
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions.

Run-Time Data
Bulk subscribe to references: To read run-time data, subscribe the references in bulk and wait for the data change
event, instead of performing an async read for each of the reference.

InTouch OMI App Limitations and Restrictions

10 InTouch OMI SDK Help


InTouch OMI SDK Help
Events and scripting are not supported.
Configuration of basic datatype properties only is supported.
Apps cannot be imported from a network share location.
Configuration of collection and array properties is not supported.
Upgrading apps is not supported.
Nested properties can be viewed and configured, but they cannot be configured with data binding.
To host the .NET controls, use the WPF element WindowsFormHost to wrap the control into WPF .
Wrap Control
<UserControl x:Class="ArchestrA.Visualization.TrendApp.TrendControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<WindowsFormsHost x:Name="FormsHost" />
</Grid>
</UserControl>

Component SDKs
The component SDK assemblies reside under the folder: C:\Program Files (x86)\ArchestrA\Framework\AcfSdk\Libs.
ArchestrA.Client.CommonUtil.dll
ArchestrA.Client.Navigation.dll
ArchestrA.Client.ProcessControls.dll
ArchestrA.Client.RuntimeData.dll
ArchestrA.Client.ViewApp.dll
ArchestrA.Client.WebControls.dll

Assemby/SDK Name Basics of Using the Assembly Additional Information


AppConfig SDK Using the AppConfig SDK EditorActivityViewModelBase Class
IEditor Interface
AppConfig Sample Class
CommonUtil SDK
RunTimeData SDK Using the RunTimeData SDK Read and Write Status
Subscribe to References
Value, Timestamp, Quality and Status
Language Namespace Using the Language Namespace
Interface Methods
Structures, Classes, and Enumerations
GraphicControl SDK Using the Graphic Control SDK Navigation Hierarchy API
Navigation SDK Using the Navigation SDK
ViewApp SDK Using the ViewApp SDK ViewApp Attributes
Web Control SDK

11 InTouch OMI SDK Help


InTouch OMI SDK Help

AppConfig SDK
The AppConfig SDK lets you build an application editor that runs in the System Platform IDE. Application developers
can use this application editor for setting global configuration options for all instances of your custom app. It is not a
requirement to include an app editor with your custom app, but if More basic apps do not need their own editors and
can be configured within the Layout Editor or the ViewApp Editor. The AppConfig SDK is exposed by the AppConfig
assembly (ArchestrA.Client.AppConfig), and includes several public interfaces and classes, including:
EditorActivityViewModelBase: This class allows the application developer to implement new activity derived from
the EditorActivityViewModelBase and add new activity in the app editor.
IEditorConfig: This interface allows the application developer to initialize, save, load and implement the app.
IEditorBase: This interface permits hosting of IEditorConfig and provides support for command, preference, save,
and load. It is implemented by Schneider Electric internal framework and is used in the App Editor.

Using the AppConfig SDK


The general workflow for using the AppConfig SDK to create an application editor is:
1. In Visual Studio, create a new Windows Desktop project and select the WPF User Control Library.
2. Add the reference assemby, ArchestrA.Client.AppConfig, to the project.
3. Implement IEditorConfig and create the App Editor class. This is needed to be able to launch the editor.
IEditorConfig is used to:
Initialize the App Editor.
Load and save app configuration data.
Load and save preference data.
Initialize activity.
IEditorConfig
/// <summary>
/// IEditorConfig must be implemented by the app developer. This
interface is used to initialize, save , load, and creating an activity
(tab) in
/// the app editor.
/// IEditorConfig is responsible for implementing the logic of saving
and loading app data.
/// IEditorConfig is also responsible for creating tabs/activities and
giving them to IEditorBase.
/// </summary>
public interface IEditorConfig
{
/// <summary>
/// InitializeEditor method will initialize App Editor with
IEditor, which hosts the editor.
/// By reflection, Wonderware internal framework finds
IEditorConfig and calls InitializeEditor by passing IEditorBase.
/// IEditorBase is a container, or actual editor.
/// </summary>
/// <param name="editor">IEditor hosts this App Editor</param>
void InitializeEditor(IEditorBase editor);
/// <summary>
/// Save method will return the data which App Editor needs to
save in the database.
/// Save method will be called by Wonderware internal framework

12 InTouch OMI SDK Help


InTouch OMI SDK Help
whenever the user clicks save.
/// Dictionary key will be the file name at time of deployment of
the app.
/// Every file will hold the value.
/// At runtime, the app will read the configuration data from the
deployed file.
/// </summary>
/// <returns> Save method returns dictionary key as string which
may be the file name and data in byte array</returns>
Dictionary<string, byte[]> Save();
/// <summary>
/// Load method called by Wonderware framework when load happens.
/// </summary>
/// <param name="appData">Returns dictionary which was saved in
the database</param>
void Load(Dictionary<string, byte[]> appData);
/// <summary>
/// App developer will create all activity and return to
framework.
/// </summary>
/// <returns>returns IEditorActivity array </returns>

IEnumerable<IEditorActivity> GetActivities();
}

4. Create an App Activity class, derived from the EditorActivityViewModelBase. Use this class to implement all
front end logic. You will also use this class to create an activity tab in the editor. For more information,
see EditorActivityViewModelBase Class.
5. Link the App Activity class with a class derived from the base View class (WPF user control).
6. Compile your code and build the app editor DLL assembly.
7. Create a folder and move the app DLL, app editor DLL, any dependent DLLs, and the appmanifest.xml file into
it.
8. From the System Platform IDE (ArchestrA IDE), use the ArchestrA App option from the Galaxy > Import menu
to select the folder that contains your app and import the app into the IDE.
9. After importing the app, open it from the Graphic Toolbox and configure the app with the editor you created.

EditorActivityViewModelBase Class
To create a tab or activity in your app editor, create a class derived from EditorActivityViewModelBase. This class
lets you override the following methods and properties:
1. Label: This sets the name of the tab that will appear at the top of the app editor.
2. RegisterCommands: This registers a command for the tab.
3. OnDeactivated: This is set when the tab is deactivated.
4. OnActivated: This is set when the tab activated.
5. OnInitialized: This is set when the tab is initialized.
EditorActivityViewModelBase has the following public methods that you can use to implement new app editor
activity:
1. SetDirty: Enables a user to save changes to the configuration in the editor.
2. IsActive: In an editor with multiple tabs, this method indicates whether a tab is active or inactive.
3. IsReadOnly: This method indicates if the editor is open in readonly mode.
EditorActivityViewModelBase contains the following protected methods/properties that can used when

13 InTouch OMI SDK Help


InTouch OMI SDK Help
implementing new app editor activity:
1. CommandManager: Register and unregister commands.
2. Editor: IEditor implemented by framework.

IEditor Interface
The IEditor interface is used in the AppConfig Editor but is implemented within the internal framework.

IEditor
public interface IEditorBase
{
/// <summary>
/// Gets the name of the editor instance.
/// </summary>
string EditorName { get; }
/// <summary>
/// Sets the editor's dirty flag to true, i.e., IsDirty returns true after
calling this method.
/// </summary>
void SetDirty();
/// <summary>
/// Gets the editor's preferences.
/// </summary>
IPreference Preferences { get; }
/// <summary>
/// Gets the editor's CommandManager.
/// </summary>
IAppCommandManagerBase AppCommandManager { get; }
/// <summary>
/// Gets a value indicating whether the editor instance is read-only
/// </summary>
bool IsReadOnly { get; }
}

AppConfig Sample Class


The following is a sample editor class that was derived from IEditorConfig.

Sample Class for AppConfig (SampleAppEditor)


namespace SampleAppEditor
{
/// <summary>
/// Exporting IEditorConfig for internal framework can open the editor
/// </summary>
[Export(typeof(IEditorConfig))]
class SampleEditor : IEditorConfig
{
IEditorBase editor;

/// <summary>
/// IEditorBase calls InitializeEditor from interal framework.
/// </summary>
/// <param name="editor">The editor holds the logic for save, load, command
manager, and preference</param>
public void InitializeEditor(IEditorBase editor)

14 InTouch OMI SDK Help


InTouch OMI SDK Help
{
this.editor = editor;
}
/// <summary>
/// This calls the interal framewok when it is loading app configuration data
into the editor.
/// Include all load-related logic in this method.
/// </summary>
/// <param name="appData"></param>
public void Load(Dictionary<string, byte[]> appData)
{
var data = appData["mydata"];
this.userText = Encoding.UTF8.GetString(data);
}
/// <summary>
/// This calls the internal framework when the save command is invoked.
/// Include all save-related logic in this method.
/// </summary>
/// <returns></returns>
public Dictionary<string, byte[]> Save()
{
this.Editor.Preferences.SetPreference("Value", "MyValue");
var byteString = Encoding.UTF8.GetBytes(this.userText);
var appData = new Dictionary<string, byte[]>();
appData.Add("mydata", byteString);
return appData;
}
/// <summary>
/// OnPreferenceLoaded is called from the framework when preferences are
loaded.
/// Include all preference-related logic in this method.
/// </summary>
public void OnPreferenceLoaded()
{
var myValue = (string)this.editor.Preferences.GetPreference("Value");
}
/// <summary>
/// GetActivities is called from the framework to get the all pages or tabs
(activities) within the editor.
/// The editor must contain at least one activity (page/tab).
/// Use this method to create all activities and return them as an array.
/// </summary>
/// <returns></returns>
IEnumerable<IEditorActivity> GetActivities()
{
return new IEditorActivity[] { new SampeleViewModel(this.editor) };
}
}
}

The following is a sample class for activity (page/tab):

Sample Class for Activity (SampleViewModel)


Sample class for activity.
public class SampleViewModel : EditorActivityViewModelBase
{
/// <summary>

15 InTouch OMI SDK Help


InTouch OMI SDK Help
/// Constructor for SampleViewModel that uses IEditorBase
/// </summary>
/// <param name="editor">IEditorBase</param>
public SampeleViewModel(IEditorBase editor)
: base(editor)
{

}
/// <summary>
/// Name of the page/tab/activity
/// </summary>
public override string Label
{
get
{
return "sample activity";
}
}
}

CommonUtil SDK
The CommonUtil SDK exposes the CommonUtil assembly (ArchestrA.Client.CommonUtil.dll) and namespace, and lets
you access common utilities, methods, and attributes. These include dispose and finalize methods, setting localized
(translated language) descriptions, and a method for setting a ResourceDictionary.

RunTimeData SDK
The main functional element of the RuntimeData SDK is a .NET assembly that lets you subscribe to, read from, and
write to either a single value reference or multiple references simultaneously. The assembly name that contains the
RuntimeData APIs is ArchestrA.Client.RuntimeData.dll, and the namespace of the assembly is
ArchestrA.Client.RuntimeData. A single value reference is a value on a single attribute for an object. The RunTime
SDK cannot be called from an external service. It can only be used inside the control of an InTouch OMI app. With the
RuntimeData SDK, you can:
Subscribe to a reference and get its current Value, Time and QualityStatus.
Write a value to a reference.
Read a value from a reference.
Perform secured/verified write operations.
The RunTimeData assembly contains two namespaces:
ArchestrA.Client.MyViewApp
ArchestrA.Client.RuntimeData
The ArchestrA.Client.MyViewApp namespace contains the following additional namespaces and classes:
Alarms
Navigation
Security
Language
Playback
Settings
System

16 InTouch OMI SDK Help


InTouch OMI SDK Help
The ArchestrA.Cient.RuntimeData namespace provides the read/write API.

Using the RunTimeData SDK


The namespace of all APIs in the RunTimeData SDK is:
ArchestrA.Client.RuntimeData
The assembly name the RunTimeData SDK uses is:
ArchestrA.Client.RuntimeData.dll
The general workflow for using the RuntimeData SDK is:
1. Implement the IRuntimeDataClient interface in the control of the app. If you need to provide the ability to
read or write any run-time data, you must implement the IRuntimeDataClient interface to receive the
DataSubscription instance. Note that data subscription is automatically suspended when the app window is
minimized, and resumes when the window is restored.
Implement IRuntimeDataClient Interface
public partial class UserControl1, IRuntimeDataClient
{
public DataSubscription DataSubscription { get; set; }
{
this.dataSubscription = dataSubscription;
}
}

2. Establish a subscription to a reference and read the value.


Subscribe to a DataReferenceSource
DataReference[] references = this.DataSubscription.Subscribe(new []
{
new DataReferenceSource("GRNode.CPULoad", (r) =>
{
// The action is executed in a background thread, so do not operate the UI
directly
this.CPUUsage = r.VT.ValueAsDouble;
}
}

The callback in the above sample is sent from a background thread. If the handler code in the App has any UI-
specific logic, the handler must execute in its Dispatcher. The above value is received in an action that has
been passed in. Alternatively, you can get the data by using references[0].VTQ.Value.
3. Optional: Asynchronous read:
Asynchronous Read
var vtqArray = await this.DataSubscription.ReadAsync
{
new [] {new DataReferenceSource("GRNode.CPULoad")} }

4. Write from subscription (see step 2 for subscription details). The following code sample shows how to write
data to the subscription.
Write to Subscription
references[0].Write(10, (r, s)=>{});
/// Or to write to an element in array:
references[0].Write(10, 0, (r, s)=>{});

17 InTouch OMI SDK Help


InTouch OMI SDK Help
5. Optional: Asynchronous write:
Asynchronous Write
var status = await this.DataSubscription.WriteAsync(new
DataRefereceSource(“Tank1.SP”), 10);

IRuntimeDataClient
Controls in an ArchestrA App must implement the IRuntimeDataClient interface to be able to read/write run-time
data.

IRuntimeDataClient
public interface IRuntimeDataClient
{
/// <summary>
/// Gets or sets the DataSubscription instance. Framework will the
DataSubscription instance to be used by client to read/write runtime data.
/// </summary>
DataSubscription DataSubscription {get; set;}
}

Read and Write Status


DataSubscription
Use the DataSubscription class from IRuntimeDataClient to read and data.

DataSubscription
public abstract class DataSubscription
{
/// <summary>
/// Read the runtime data asynchronously.
/// </summary>
/// <param name="dataReferenceSources">The data reference source
/// array</param>
/// <returns>The VTQ array of the references</returns>
public abstract Task<VTQ[]> ReadAsync(DataReferenceSource[]
dataReferenceSources);
/// <summary>
/// Write the runtime data asynchronously.
/// When writing to an ArchestrA attribute in which security is
/// SecuredWrite or VerifiedWrite, the corresponding pop-up dialog box
/// will automatically popup and the method will return when the dialog
/// box is dismissed and the data is either written to the source or fails.
/// </summary>
/// <param name="dataReferenceSource">The data reference source</param>
/// <param name="value">The value to be written</param>
/// <returns>The status of the write operation</returns>
public abstract Task<WriteOperationStatus> WriteAsync(DataReferenceSource
dataReferenceSource , object value);
/// <summary>
/// Subscribe the runtime data references.
/// </summary>
/// <param name="dataReferenceSources">The data reference source array</param>
/// <returns>The subscribed data reference array</returns>

18 InTouch OMI SDK Help


InTouch OMI SDK Help
public abstract DataReference[] Subscribe(DataReferenceSource[]
dataReferenceSources);
/// <summary>
/// Unsubscribe the runtime data references.
/// </summary>
/// <param name="dataReferences">The data reference array</param>
public abstract void Unsubscribe(DataReference[] dataReferences);
/// <summary>
/// Unsubscribe all runtime data references.
/// </summary>
public abstract void UnsubscribeAll();
}

WriteOperationStatus
Use the WriteOperationStatus class to receive write status when writing data to a reference.

WriteOperationStatus
public enum WriteOperationStatus
{
/// <summary>
/// Indicates success
/// </summary>
WriteSuccess = 0,
/// <summary>
/// Indicates failure
/// </summary>
WriteFailed = 1,
/// <summary>
/// Indicates failure because of application authentication issues
/// </summary>
ApplicationAuthenticationError = 2,
/// <summary>
/// Indicates failure because of user authentication issues
/// </summary>
UserAuthenticationError = 3,
/// <summary>
/// Indicates failure because of user authorization issues
/// </summary>
UserAuthorizationError = 4,
/// <summary>
/// Indicates failure because of unsupported operation
/// </summary>
NotSupportedOperation = 5,
/// <summary>
/// Indicates failure because the item is already deleted
/// </summary>
ItemAlreadyDeletedOrDoesNotExist = 9,
/// <summary>
/// Indicates failure because the item is invalid
/// </summary>
InvalidMonitoredItems = 10,
/// <summary>
/// Indicates failure because the operation failed
/// </summary>
OperationFailed = 11,
/// <summary>
/// Indicates failure because of no connection

19 InTouch OMI SDK Help


InTouch OMI SDK Help
/// </summary>
WriteFailedNoConnection = 12
}

Subscribe to References
DataReferenceSource
The DataReferenceSource class is used to define and subscribe to the reference source, and to receive data from it.

DataReferenceSource
public class DataReferenceSource
{
/// <summary>
/// Initializes a new instance of the DataReferenceSource class.
/// </summary>
/// <param name="referenceString">The reference string</param>
/// <param name="owningObject">The owning object name</param>
/// <param name="dataChangedAction">The action to receive the data/quality
change</param>
public DataReferenceSource(string referenceString, string owningObject,
Action<DataReference> dataChangedAction);
/// <summary>
/// Initializes a new instance of the DataReferenceSource class.
/// </summary>
/// <param name="referenceString">The reference string</param>
/// <param name="dataChangedAction">The action to receive the data/quality
change</param>
public DataReferenceSource(string referenceString, Action<IDataReference>
dataChangedAction);
/// <summary>
/// Gets the owning object.
/// </summary>
public string OwningObject { get; }
/// <summary>
/// Gets the reference string.
/// </summary>
public string ReferenceString { get; }
/// <summary>
/// Gets the action to receive the data/quality update.
/// The Action passes the DataReference that triggers the data change.
/// </summary>
public Action<IDataReference> DataChangedAction { get; }
}

DataReference
Once you have subscribed to the DataReferenceSource, you can receive the DataReference from it. The
DataReference can then be used to read/write the run-time data.

DataReference
public abstract class DataReference
{
/// <summary>
/// Gets the VTQ of the data item
/// </summary>

20 InTouch OMI SDK Help


InTouch OMI SDK Help
public Vtq Vtq { get; }
/// <summary>
/// Initiate the process to write the value to the reference
/// </summary>
/// <param name="value">The value to be written</param>
/// <returns>The status of the initiation process</returns>
public abstract WriteOperationStatus Write(object value);
/// <summary>
/// Initiate the process to write the value to the element of the referenced
array.
/// </summary>
/// <param name="value">The value to be written</param>
/// <param name="elementIndex">The index of array element</param>
/// <returns>The status of the initiation process</returns>
public abstract WriteOperationStatus Write(object value, int elementIndex);
/// <summary>
/// Initiate the process to write the value to the reference. System will call
back to update the write status there after
/// </summary>
/// <param name="value">The value to be written</param>
/// <param name="writeStatusChangedAction">The call back for the write status.
The DataReference is the reference to be written; The StatusSettingType contains the
status of the Write operation.</param>
/// <returns>The status of the initiation process</returns>
public abstract WriteOperationStatus Write(object value, Action<DataReference,
StatusSettingType> writeStatusChangedAction);
/// <summary>
/// Initiate the process to write the value to the element of the referenced
array. System will call back to update the write status there after
/// </summary>
/// <param name="value">The value to be written</param>
/// <param name="elementIndex">The index of array element</param>
/// <param name="writeStatusChangedAction">The call back for the write status.
The DataReference is the reference to be written; The StatusSettingType contains the
status of the Write operation.</param>
/// <returns>The status of the initiation process</returns>
public abstract WriteOperationStatus Write(object value, int elementIndex,
Action<DataReference, StatusSettingType> writeStatusChangedAction);
}

Value, Timestamp, Quality and Status


VTQ
The VTQ class represents the value, timestamp, and quality status of the data item. The data item is also called the
IData Reference.

VTQ
public abstract class VTQ
{
/// <summary>
/// Gets the value of the data item.
/// </summary>
public abstract DataValue Value { get; }
/// <summary>
/// Gets the quality and status of the data item.
/// </summary>

21 InTouch OMI SDK Help


InTouch OMI SDK Help
public abstract QualityStatus QualityStatus { get; }
/// <summary>
/// Gets the time stamp represented in UTC.
/// </summary>
public abstract DateTime Timestamp { get; }
}

Value
Value represents the value of the data item value and related data conversion utility methods.

Value
public class Value
{
/// <summary>
/// Gets or sets the raw data value contained in this class.
/// </summary>
public abstract object RawValue { get; }
/// <summary>
/// Gets the value as type Integer.
/// </summary>
public abstract int ValueAsInt32 { get; }
/// <summary>
/// Gets the value as type Float.
/// </summary>
public abstract float ValueAsFloat { get; }
/// <summary>
/// Gets the value as type Double.
/// </summary>
public abstract double ValueAsDouble { get; }
/// <summary>
/// Gets the value as type String.
/// </summary>
public abstract string ValueAsString { get; }
/// <summary>
/// Gets the value as type DateTime.
/// </summary>
public abstract DateTime ValueAsDateTime { get; }
/// <summary>
/// Gets the value as type Duration.
/// </summary>
public abstract TimeSpan ValueAsDuration { get; }
/// <summary>
/// Gets the value as type bool.
/// </summary>
/// <value><c>true</c> if [value as bool]; otherwise, <c>false</c>.</value>
public abstract bool ValueAsBool { get; }
/// <summary>
/// Gets a value indicating whether this instance is empty
/// </summary>
/// <value><c>true</c> if this instance is empty; otherwise,
<c>false</c>.</value>
public abstract bool IsEmpty { get; }

/// <summary>
/// Gets a value indicating whether the value is an array.
/// </summary>
/// <value><c>true</c> if this instance is array; otherwise,

22 InTouch OMI SDK Help


InTouch OMI SDK Help
<c>false</c>.</value>
public abstract bool IsArray { get; }
/// <summary>
/// Gets the array value if the value is holding an array.
/// </summary>
/// <returns></returns>
public abstract Array Array { get; }
/// <summary>
/// Gets the number of elements in the array if the value is holding array
data.
/// </summary>
/// <returns>The number of elements in the array.</returns>
public abstract int ArraySize { get; }
/// <summary>
/// If the value is holding an array, this returns an element from the array.
/// </summary>
/// <param name="elementIndex">value of elementindex</param>
/// <returns>object value</returns>
public abstract object GetArrayElement(int elementIndex);
}

QualityStatus
The QualityStatus class represents the data quality and status, and related helper methods.

QualityStatus
public abstract class QualityStatus
{
/// <summary>
/// This defines the bits when the quality does not exist.
/// </summary>
public const int QualityNotExist = -1;
/// <summary>
/// Gets the status setting enum.
/// </summary>
public abstract StatusSettingType StatusSetting { get; }
/// <summary>
/// The data quality follows OPC UA standard, or QualityNotExist if it does not
exist.
/// </summary>
public abstract int OpcUaQuality { get; }

/// <summary>
/// The data quality used by ArchestrA, or QualityNotExist if it does not
exist.
/// </summary>
public abstract int MxQuality { get; }

/// <summary>
/// Returns true if the quality is good.
/// </summary>
/// <returns>True if good</returns>
public abstract bool IsGood();

/// <summary>
/// Returns true if the quality is bad.
/// </summary>
/// <returns>True if bad</returns>

23 InTouch OMI SDK Help


InTouch OMI SDK Help
public abstract bool IsBad();
/// <summary>
/// Returns true if the quality is uncertain.
/// </summary>
/// <returns>True if uncertain</returns>
public abstract bool IsUncertain();
/// <summary>
/// Returns true if the quality is initializing.
/// </summary>
/// <returns>True if initializing</returns>
public abstract bool IsInitializing();
}

StatusSettingType
The StatusSettingType enum represents the data status settings used in the Galaxy style library configuration.

StatusSettingType
public enum StatusSettingType : byte
{
/// <summary>
/// Represents a Communication Error type.
/// </summary>
Communication = 0,
/// <summary>
/// Represents a Configuration Error type.
/// </summary>
Configuration = 1,
/// <summary>
/// Represents a Pending Error type.
/// </summary>
Pending = 2,
/// <summary>
/// Represents an Operational Error type.
/// </summary>
Operational = 3,
/// <summary>
/// Represents a Software Error type.
/// </summary>
Software = 4,
/// <summary>
/// Represents a Security Error type
/// </summary>
Security = 5,
/// <summary>
/// Represents a Warning Error type.
/// </summary>
Warning = 6,
/// <summary>
/// Represents Out Of Service.
/// </summary>
OutOfService = 7,
/// <summary>
/// Represents a Device Failure.
/// </summary>
DeviceFailure = 8,
/// <summary>
/// Represents a Bad Error type.

24 InTouch OMI SDK Help


InTouch OMI SDK Help
/// </summary>
Bad = 9,
/// <summary>
/// Represents an Uncertain Error type.
/// </summary>
Uncertain = 10,
/// <summary>
/// Represents an Initializing Error type.
/// </summary>
Initializing = 11,
/// <summary>
/// Represents Good status.
/// </summary>
Good = 12,
/// <summary>
/// Represents an Unknown type.
/// </summary>
Unknown = 13
}

Language Namespace
If multiple languages have been configured in a Galaxy, you can manage the languages and locales in an application.
This allows users to implement multiple languages/locales in your application during configuration, and to change the
language during run time. Three attributes in the language namespace are provided for setting language and locale:
CurrentLanguage: This attribute contains the current language, for example, "English," and can be set
during run time to change the application language.
CurrentCultureInfo: This attribute contains locale-type information, for example, "en-US," and can be set
during run time to change the locale.
CurrentLCID: This attribute contains a numeric identifier that corresponds to the locale, for example, "01,"
and can be set during run time to change the locale.
In addition, the language namespace includes three properties. All use an array that holds ;language and locale IDs
that currently configured.
Languages
Lcids:
CultureInfos

Attributes
Language attributes are exposed in the Titlebar sample app when the Language property is enabled. A dropdown list
of configured languages is displayed in the ViewApp, and users can then change the ViewApp language during run
time. You can use the same language namespace attributes and properties in your own custom apps.

CurrentLanguage Attribute

The CurrentLanguage attribute holds the currently-configured language for the ViewApp. The CurrentLanguage
method returns the currently-configured language for the ViewApp.

CurrentLanguage
/// <summary>
/// Gets or sets the current language.
/// </summary>
/// <value>

25 InTouch OMI SDK Help


InTouch OMI SDK Help
/// The current language.
/// </value>
public static string CurrentLanguage

CurrentLCID Attribute

The CurrentLCID attribute holds the currently-configured locale ID for the ViewApp. The CurrentLCID is an integer
value that corresponds to the currently-selected language for the ViewApp.

CurrentLCID
/// <summary>
/// Gets or sets the current LCID.
/// </summary>
/// <value>
/// The current LCID.
/// </value>
public static int CurrentLCD

CurrentCultureInfo Attribute

The CurrentCultureInfo attribute holds the currently-configured locale information, for example, EN-us (English-
United States), for the ViewApp. The CurrentCultureInfo method returns the currently-configured locale for the
ViewApp.

CurrentCultureInfo
Type your example code here. It will be automatically colorized when you switch to
Preview or build the help system.

Properties
Languages Property

The Languages property uses an array that lists the languages that are configured in language settings. The languages
are set in the System Platform IDE, under Galaxy > Configure > Languages. The Language property includes the
Languages index. The Languages index number is exactly the same as the LCID index number in the LCIDs array and
the CultureInfo index number in the CulturesInfo array.

Languages
/// <summary>
/// Gets the list of configured languages. The Languages array will have the same size
as the LCIDs array.
/// The Language index within the Languages array, the LCID index within the LCIDs
array, and the CultureInfos index within the CultureInfos array will all have the same
index number.
/// </summary>
/// <value>
/// The configured languages.
/// </value>
public static string[] Languages

Lcids Property

The Lcids property uses an array that lists the LCIDs (language and locale IDs) that are configured in language
settings. The Lcids property is set in the System Platform IDE, under Galaxy > Configure > Languages. The Lcids

26 InTouch OMI SDK Help


InTouch OMI SDK Help
property includes the LCID index. The LCID index number is the exactly the same number as the Languages index
number in the Languages property and the CultureInfo index number in the CulturesInfo property.

Lcids
/// <summary>
/// Gets the LCIDs. The LCID array will have the same size as the Languages array.
/// The LCID index within the Lcids array, the Languages index within the Languages
array, and the CultureInfos index within the CultureInfos array will all have the same
index number.
/// </summary>
/// <value>
/// The configured Lcids.
/// </value>
public static string[] Lcids

CultureInfos Property

The CultureInfos property uses an array that lists the CultureInfos numbers (language and locale IDs) that are
configured in language settings. The CultureInfos property is set in the System Platform IDE, under Galaxy >
Configure > Languages. The CultureInfos property includes the CultureInfo index. The CultureInfo index number is
the exactly the same number as the Language index number in the Languages property and the LCID index number in
the LCIDs property.

CultureInfos
/// <summary>
/// Gets the Culture Information. The CultureInfos array will have the same size as the
Languages array.
/// The CultureInfos index within the CultureInfos array, the Languages index within
the Languages array, and the LCID index within the Lcids array will all have the same
index number.
/// </summary>
/// <value>
/// The configured culture information.
/// </value>
public static string[] CultureInfos

Using the Language Namespace


The language namespace is contained within the RuntimeData assembly. The general parameters for using the
language namespace, and accessing namespace properties and attributes, is as follows:
To call the current language (CurrentLanguage attribute):
Call CurrentLanguage
var CurrentLanguage = ArchestrA.Client.MyViewApp.Language.CurrentLanguage;
// Get property change notification from event subscription.
ArchestrA.Client.MyViewApp.Language.PropertyChanged + =
this.LanguagePropertyChanged;
private void LanguagePropertyChanged(object sender, PropertyChangedEventArgs e)
// e.PropertyName will return the "CurrentLanguage" language attribute value.

To call the current locale ID (CurrentLCID attribute):


Call CurrentLCID

27 InTouch OMI SDK Help


InTouch OMI SDK Help
var CurrentLCID = ArchestrA.Client.MyViewApp.Language.CurrentLCID;
// Get property change notification from event subscription.
ArchestrA.Client.MyViewApp.Language.PropertyChanged + =
this.LanguagePropertyChanged;
private void LanguagePropertyChanged(object sender, PropertyChangedEventArgs e)
// e.PropertyName will return the "CurrentLCID" language attribute value.

To call the current culture information (CurrentCultureInfo attribute):


Call CurrentCultureInfo
var CurrentLCID = ArchestrA.Client.MyViewApp.Language.CurrentLCID;
// Get property change notification from event subscription.
ArchestrA.Client.MyViewApp.Language.PropertyChanged + =
this.LanguagePropertyChanged;
private void LanguagePropertyChanged(object sender, PropertyChangedEventArgs e)
// e.PropertyName will return the "CurrentLCID" language attribute value.

To return the list of configured languages:


Return Languages
var languages = ArchestrA.Client.MyViewApp.Language.Languages;

To return the list of configured LCIDs:


Example Title
var lcids= ArchestrA.Client.MyViewApp.Language.Lcids;

To return the list of configured CultureInfos:


Return CultureInfos
var CultureInfos = ArchestrA.Client.MyViewApp.Language.CultureInfos;

Interface Methods
Get Current Language Method
LocaleItem GetCurrentLanguage()
Returns the currently-configured Locale ID (LCID) and the language name in the LocaleItem structure.

Subscribe to Locale Change Event Method


EventHandlerLocaleChanged<LocaleEventArgs>LocaleChanged
Subscribes to an event to monitor if the current Locale has changed.

Structures, Classes, and Enumerations


LocateItem (structure): this holds the locale identifier (LCID) and the language name.

28 InTouch OMI SDK Help


InTouch OMI SDK Help

Property Name Property Type Description Default


Value
LCID Integer Gets the locale ID --
LanguageName String Gets the language name that corresponds to the --
Locale ID

LocaleEverntArgs Class

Property Name Property Type Description Default


Value
NewLCID Integer This indicates the numeric identifier for the new --
LCID
OldLCID Integer This indicates the numeric identifier of the old --
LCID

GraphicControl SDK
The ArchestrA.Client.ProcessControls assembly contains the Graphic Control SDK, which exposes reusable graphic
and alarm adorner controls. The graphic control exposes the following dependency properties:
GraphicName
OwningObject
EnableInteractiveContent
EnableTriggeringNavigation

Using the Graphic Control SDK


The general workflow for using the GraphicControl SDK is:
1. Show the GraphicControl in an ArchestrA App. Create a reference to the ArchestrA.Client.ProcessControls
assembly and name, and use the control as shown below:

GraphicControl Reference
// Create a reference
xmlns:controls="clr-
namespace:ArchestrA.Client.ProcessControls;assembly=ArchestrA.Client.ProcessControls"
// Use the control
<controls:GraphicControl GraphicName="{Binding SymbolName}"}/>

2. Retrieve the content from a navigation path, based on filter options as shown below. Refer to the navigation
model assembly (ArchestrA.Client.Navigation.NavigationModel):

Retrieve Content
public static ArchestrA.Client.Navigation.ContentData[]
GetContentInHierarchy(string navigationHierarchyPath,

29 InTouch OMI SDK Help


InTouch OMI SDK Help
ArchestrA.Client.Navigation.FilterOptions filterOptions ContentData [] contentData
= NavigationModel.GetContentInHierarchy
(@"\\Home\NavigationItem2", FilterOptions = new FilterOptions()
{ ContentType = "", ContentName = "Clock*", LevelsOfSearch = LevelsOfSearch.All

3. Show the GraphicControl in the ACF app. The GraphicControl is defined under the namespace
ArchestrA.Client.ProcessControls, and the assembly that defines the APIs is ArcestrAClient.ProcessControls.DLL.
4. Retrieve the content from the navigation path, baseed on the filter options you have set. The search content API
s defined under the namespace ArchestrA.Client.Navigation. The assembly defined these APIs is
ArchestrA.Client.Navigation.dll.

GraphicControl Properties
GraphicControl is a user control, wrapped around the InTouch OMI visualization module. This provides an easy to
instantiate and display the InTouch OMI visualization module in any ACF app. GraphicControl abstracts all of the logic
for instantiating and rendering graphics in a XAML template, and exposes the following properties. You can bind these
properties within the apps that you write to use their functionality.
GraphicName: [Required] The name of the graphic to be displayed in an app. You must provide a value for
the GraphicName. The syntax for setting the GraphicName is ObjectName.SymbolName.
OwningObject: [Optional] This sets the owning object of the graphic. If a value for OwningObject is not
provided, the tagname of the object associated with the graphic is used.
EnableInteractiveContent: If true, this enables the content to be interactive. In a graphic, this property
controls whether or not user-interaction animations are enabled. The default setting this property is true.
EnableTriggeringNavigation: If true, clicking on content that does not include an interaction animation
triggers a move to the naviation item linked to the content. The default setting for this property is false.

Navigation Hierarchy API


This Navigation API is exposed to retrieve content, based on a set of filter options. FilterOptions is the class you can
use to specify search criteria.

FilterOptions Class
/// <summary>
This class holds the filter options applied to a specific navigation item.
/// </summary>
public class FilterOptions
{
/// <summary>
/// Gets or sets option Levels of Search.
/// Provides the levels of search performed on the hierarchy of a navigation
path.
/// </summary>
public LevelsOfSearch LevelsOfSearch { get; set; }

/// <summary>

/// Gets or sets the option NavigationSearchMode.


/// Provides the navigation search mode for the given navigation path.
/// </summary>
public NavigationSearchMode NavigationSearchMode { get; set; }

/// <summary>

/// Gets or sets SortOrder option.


/// SortOrder controls how items are sorted after they are returned to you
/// </summary>
public SortOrder SortOrder { get; set; }

30 InTouch OMI SDK Help


InTouch OMI SDK Help

/// <summary>
/// Gets or sets option ContentType
/// 1) This field should be one of the content types in the system
/// 2) This field is ignored if the value is empty.
/// </summary>
public string ContentType { get; set; }
}

FilterOptions Search Options


ContentName: This option specifies the name of the content that you are searching for on a particular
navigation hierarchy path.
The value of ContentName must be the partial or exacgt name3 of the content.
Wildcard characters can be used.
The value of ContentName is ignored if it is empty.
ContentType: This option specifies the type of content that you are searching for on a particular navigation
hierarchy path.
The assigned value of ContentType mustbe the exact content type of the content.
The value of ContentType is ignored if it is empty.
SortOrder: This option controls how returned content is sorted after a search.

SortOrder
/// <summary>
/// This option controls how are sorted from the API
/// </summary>
public enum SortOrder
{
/// <summary>
/// This is the default option, which fills the control based on the order in which
it finds the content.
/// This is similar to depth-first search
/// </summary>
None = 0,

/// <summary>
/// Sorts content based on name in alphabetic order.
/// </summary>
Alphabetical
}

Navigation Search Mode: This option specifies the navigation search mode that determines which navigation
path hierarchy is considered at the API level.

Navigation Search Mode


/// <summary>
/// This option provides the different navigation search modes that system allows .
/// </summary>
public enum NavigationSearchMode
{
/// <summary>

/// In FixedLocation mode, a search starts from a specific navigation path node provided
by the user.
/// </summary>
FixedLocation = 0,

31 InTouch OMI SDK Help


InTouch OMI SDK Help

/// <summary>
/// In CurrentPath mode, a search starts from the current navigation path node
selected by the user.
/// This is same path as MyViewApp.Navigation.CurrentPath
/// </summary>
CurrentNav CurrentPath,

/// <summary>

/// In ChildrenAlone mode, a search starts from the child navigation nodes of a parent
/// node specified by the user.
/// </summary>
ChildrenAlone
}

LevelsOfSearch: This option provides the levels of search to be performed on a specified navigation path
pathhierarchy.

LevelsOfSearch
/// <summary>
/// This option provides the different levels of search that system allows
/// </summary>
public enum LevelsOfSearch
{
/// <summary>
/// Searches all levels of a navigation hierarchy.
/// </summary>
All = 0,

/// <summary>
/// Searches only one level of a navigation hierarchy.
/// </summary>
SearchesOneLevel,

/// <summary>

/// Searches two levels of a navigation hierarchy


/// </summary>
SearchesTwoLevels,

/// <summary>

/// Searches three levels of a navigation hierarchy


/// </summary>
SearchesThreeLevels
}

Return Type: The return type of the API is an array of the ContentData. The ContentData array contains
information such as the name of the content and its owning object.

Return Type
/// <summary>

/// This class holds content information, such as name and owning object.
/// </summary>
public class ContentData
{
/// <summary>

32 InTouch OMI SDK Help


InTouch OMI SDK Help
/// Gets the name of the content.
/// </summary>
public string ContentName { get; }

/// <summary>
/// Gets the owning object of the content.
/// </summary>
public string OwningObject { get; }
}

Navigation SDK
Navigation in an InTouch OMI Project (Galaxy) allows the user to leverage the existing asset model and existing
Graphic Toolbox folder structure (GTB), or build a custom hierarchy of run-time behaviors. These behaviors allow the
runtime user to perform various actions to show content, browse information, etc. The Navigation SDK is designed to
allow you to build a visible control, such as the NavTreeControl, that shows either your custom build hierarchy or
existing hierarchies in the Galaxy. The Navigation SDK is delivered as ArchestrA.Client.Navigation.dll, which is
installed with the remainder of the InTouch OMI assemblies as part of the ArchestrA IDE installation.
The main functional element of the Navigation SDK is a .NET assembly that lets you retrieve the underlying
navigation model and NavigationItems to provide an easy way to access the navigation hierarchies in your ACF apps.
The Navigation SDK exposes the following classes:
NavigationModel
NavigationItem
NavigationException
The namespace for these classes is:
ArchestrA.Client.Navigation
The assembly name is:
ArchestrA.Client.Navigation.DLL

Using the Navigation SDK


NavigationModel
This class is exposed to retrieve the underlying ViewApp Navigation Model, and encapsulates your navigation hierarchy, either
built from scratch or using the Asset Model as input. This hierarchy holds Navigation Items for use in run time, which are
primary consumed by Navigation-aware controls.

NavigationModel
public abstract class NavigationModel
{
/// <summary>
/// Gets the default NavigationModel of the ViewApp
/// </summary>
public static NavigationModel ViewAppNavigationModel { get; }

/// <summary>
/// Gets the root item of the model
/// </summary>
public abstract NavigationItem RootItem { get; }

/// <summary>
/// Gets the collection of navigation items.

33 InTouch OMI SDK Help


InTouch OMI SDK Help
/// </summary>
/// <returns> Returns an observable collection of immediate child navigation items
/// </returns>
public abstract ReadOnlyObservableNavigationItemCollection Items { get; }

/// <summary>
/// Gets the item for the given navigation item path
/// </summary>
/// <param name="navigationItemFullPath"> Full path or URI of a particular hierarchy item
/// </param>
/// <returns> Navigation item
/// </returns>
public abstract NavigationItem GetItemBypath(string navigationItemFullPath);

/// <summary>
/// Retrieves the content available under the navigation hierarchy path, based on the the
given filter options
/// </summary>
/// <param name="NavigationHierarchyPath"> The navigation hierarchy path. This should be
something like
/// \\Home\NavigationItem1
/// </param>
/// <param name="FilterOption"> This is the filter criteria to retrieve content
/// </param>
/// <returns> Array of ContentData </returns>
public abstract ContentData[] GetContentInHierarchy(string navigationHierarchyPath,
FilterOptions filterOptions);
}

NavigationItem
This class is exposed to define how individual navigation items in the underlying ViewApp Navigation Model should appear. It
contains all required information to show a visual representation of a navigation item in various forms.

NavigationItem
public abstract class NavigationItem
{
/// <summary>
/// Gets or sets the actual name of the Navigation Item.
/// </summary>
public virtual string Name { get;}

/// <summary>
/// Gets or sets the friendly name of the Navigation Item to be shown on
/// navigation-aware control items.
/// </summary>
public virtual string Title { get;}

/// <summary>

/// Gets or sets a value indicating whether or not the Navigation Item has errors.
/// </summary>
/// <value>
/// <c>true</c> if [HasErrors]; otherwise, <c>false</c>.
/// </value>
public virtual bool HasErrors { get;}
/// <summary>
/// Gets or sets the errors for this Navigation Item.
/// </summary>
public virtual IEnumerable Errors { get;}

/// <summary>

34 InTouch OMI SDK Help


InTouch OMI SDK Help
/// Gets or sets the parent of the Navigation Item.
/// </summary>
public NavigationItem Parent { get; }
/// <summary>
/// Gets a value indicating whether Navigation Item [has items].
/// </summary>
/// <value>
/// <c>true</c> if [has items]; otherwise, <c>false</c>.
/// <value>
public abstract bool HasItems { get; }

/// <summary>
/// Gets the child item collection.
/// </summary>
/// <returns> An observable collection of navigation item that are immediate child items
of this instance.
/// </returns>
public abstract ReadOnlyNavigationItemCollection Items { get; }
/// <summary>
/// Gets the previous sibling.
/// </summary>
/// <returns>NavigationItem
/// </returns>
navigationItem public NavigationItem PreviousSibling

/// <summary>
/// Gets the next sibling.
/// </summary>
/// <returns>NavigationItem
/// </returns>
public NavigationItem NextSibling

/// <summary>
/// Gets a value indicating the path of the item in its hierarchy.
/// </summary>
public string Path

/// <summary>

/// Gets or sets a value that indicates the Access Level of the configured Nav Item.
/// </summary>
public virtual int AccessLevel { get; }

/// <summary>
/// Gets the item located at a given hierarchy path.
/// </summary>
/// <param name="fullPath"> The full or relative path of the item to be retrieved.
/// </param>
/// <returns> Requested Navigation Item
public abstract NavigationItem GetItem(string fullPath);
}

NavigationException

NavigationException
/// <summary>
/// A custom exception class that wraps the exception/error information related to the
Navigation Extension.
/// </summary>
[Serializable]
public class NavigationException : Exception
{

35 InTouch OMI SDK Help


InTouch OMI SDK Help
/// <summary>
/// Initializes a new instance of the <see cref="NavigationException"/> class.
/// </summary>
public NavigationException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="NavigationException"/> class.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public NavigationException(string message) : base(message)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="NavigationException"/> class.
/// </summary>
/// <param name="message">The error message that explains the reason for the
exception.
/// </param>
/// <param name="innerException">The exception that is the cause of the current
exception, or a null reference
/// (nothing in Visual Basic) if no inner exception is specified.
/// </param>
public NavigationException(string message, Exception innerException)
: base(message, innerException)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="NavigationException"/> class.
/// </summary>
/// <param name="info">The <see
cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the
/// serialized object data about the exception being thrown.
/// </param>
/// <param name="context">The <see
cref="T:System.Runtime.Serialization.StreamingContext" /> that contains
/// contextual information about the source or destination.
/// </param>
protected NavigationException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
}

ViewApp SDK
The ViewApp SDK is the core SDK assembly. It exposes the ViewApp assembly (ArchestrA.Client.ViewApp.dll) and lets
you access InTouch OMI ViewApp features, such as displaying content and activating slide-in panes. It also contains
the language namespace, and provides access to language attributes that can allow users to localize a running
ViewApp. Localizing a ViewApp can include changing the language as well as how other settings, such as numerical
formats and time/date are rendered.
The ViewApp SDK provides access to the following content-rendering features:
ShowContent
ShowLayout
ActivateSlideInPane

36 InTouch OMI SDK Help


InTouch OMI SDK Help
The ViewApp SDK also provides access to the following language features:
CurrentLanguage
CurrentLCID
CurrentCultureInfo
Languages
Lcids

Using the ViewApp SDK


Use the ViewApp SDK to set the layout state (minimize/maximize the ViewApp window), close the ViewApp, and set
the position of, and activate, a slide-in pane.

Methods and Enums

ActivateSlideInPane

The ActivateSlideInPane() method is used to activate the slide-in-pane. This method has two parameters:
Control: This is the framework element that triggers the ActivateSlideInPane action. In the Navigation
hierarchy, it searches for the parent window that contains the element, and activates the slide-in pane at
that level of the hierarchy.
PanePosition: This is an enumeration with four possible values (Left, Right, Top, Bottom). This determines
which slide-in pane is activated.

ActivateSlideInPane
/// <summary>
/// Activates Slide-In Pane (Left,Right,Top,Bottom)
/// </summary>
/// <param name="control">Reference to control that was added to the pane</param>
/// <param name="slideInPanePosition">Slide-In Pane position</param>
public abstract void ActivateSlideInPane(object control, SlideInPanePosition
panePosition);

SetLayoutState

The SetLayoutState() method is used to maximize, minimize, and restore layouts when the user selects the
corresponding button. This method has two parameters:
Control: This is the framework element that triggers the SetLayoutState action. In the Navigation hierarchy, it
searches for the parent window that contains the element, and maximizes, minimizes, or restores the window at that
level of the hierarchy.
WindowState: This is an enumeration from System.Windows.WindowState. It has three values:
Normal
Minimize
Restore

CloseLayout

The CloseLayout() method is used to close the Layout window. This method has one parameter:
Control: This is the framework element that triggers the CloseLayout action. In the Navigation hierarchy, it
searches for the parent window that contains the element, and closes the layout at that level of the
hierarchy.

CloseLayout

37 InTouch OMI SDK Help


InTouch OMI SDK Help
/// <summary>
/// Closes the Layout Window
/// </summary>
/// <param name="control">object. For instance, FrameworkElement</param>
public abstract void CloseLayout(object control);

SlideInPanePosition

The SlideInPanePosition enumeration is passed to the ActivateSlideInPane API. It has four values to set the position of
the slide-in pane:
Top
Bottom
Left
Right

SlideInPanePosition
public enum SlideInPanePosition
{
/// <summary>
/// Indicates left slide in pane
/// </summary>
Left = 0,
/// <summary>
/// Indicates right slide in pane
/// </summary>
Right = 1,
/// <summary>
/// Indicates top slide in pane
/// </summary>
Top = 2,
/// <summary>
/// Indicates bottom slide in pane
/// </summary>
Bottom = 3,
}

ViewApp Attributes
You can access references and enable or disable features through the use of ViewApp attributes. There are seven
attribute categories: Alarms, Language, Navigation, Playback (historical playback), Security, Settings, and System.

List of Attributes by Category

Attribute Attribute Name Description Data Type


Category
Alarms ShowCriticalAlarms Gets or sets a value indicating that critical alarms boolean
should be shown
ShowHighAlarms Gets or sets a value indicating that high alarms should boolean

38 InTouch OMI SDK Help


InTouch OMI SDK Help

Attribute Attribute Name Description Data Type


Category
be shown
ShowMediumAlarms Gets or sets a value indicating that medium alarms boolean
should be shown
ShowLowAlarms Gets or sets a value indicating that low alarms should boolean
be shown
ShowUnAckedAlarms Gets or sets a value indicating that UNacknowledged boolean
alarms should be shown
ShowAckedAlarms Gets or sets a value indicating that acknowledged boolean
alarms should be shown
ShowReturnToNormalAlarms Gets or sets a value indicating that unacknowledged boolean
alarms that have returned to normal should be shown
Language CurrentLanguage Gets or sets the currently-selected language string
CurrentLCID Gets or sets the locale ID for the currently-selected integer
language
CurrentCurrentCultureInfo Gets or sets the locale for the currently-selected string
language
Navigation CurrentAsset Gets or sets the currently-selected asset string
CurrentArea Gets or sets the currently-selected area string
CurrentPath Gets or sets the currently-selected path string
CurrentTitle Gets the currently-selected title string
CurrentAssetPath Gets the currently-selected asset path string
CurrentAssetTitle Gets the currently-selected asset title string
CurrentAreaPath Gets the currently-selected area path string
CurrentAreaTitle Gets the currently-selected asset title string
Root Gets the navigation root string
RootPath Gets the navigation root path string
RootTitle Gets the navigation root title string
Parent Gets the name of the parent node string
ParentPath Gets the path of the parent node string
ParentTitle Gets the title of the parent node string
PrevSibling Gets the name of the previous sibling navigation node string
PrevSiblingPath Gets the path of the previous sibling navigation node string
PrevSiblingTitle Gets the title of the previous sibling navigation node string
NextSibling Gets the name of the next sibling navigation node string
NextSiblingPath Gets the path of the next sibling navigation node string
NextSiblingTitle Gets the title of the next sibling navigation node string
CurrentRootArea Gets the root area name of the current asset, if the string
CurrentAsset is a valid asset
CurrentRootAreaPath Gets the fully-qualified name of the current root area string

39 InTouch OMI SDK Help


InTouch OMI SDK Help

Attribute Attribute Name Description Data Type


Category
item
CurrentRootAreaTitle Gets the user-friendly name of the root area of the string
current asset. If the root area is not part of the
navigation model, this value will be empty
Playback Enabled Enables/disables historical playback. When true, other boolean
playback attributes are initialized and playback is
enabled
StartTime Sets the start time for historical playback DateTime
EndTime Sets the end time for historical playback DateTime
CurrentTime Sets the current time for historical playback DateTime
Speed Sets the historical playback speed (0 = stopped; 1 = integer
normal playback; >1 = fast forward)
Playing Enables/disables playback boolean
Security LoggedIn Returns true or false to indicate if a user is logged into boolean
the ViewApp
LoggedInUserName Gets the user name of the logged-in user string
LoggedInAccessLevel Gets the access level of the security role assigned to integer
the logged-in user
LastSuccessfulLogin Gets the UTC timestamp of the most recent successful DateTime
log in to the ViewApp. If no one is currently logged in
and the ViewApp is running, returns 01/01/0001
00:00:00
LoggedInUserWinToken Gets the Windows account token of the currently SafeHandle
logged-in user
LoggedInUserSsoToken Gets the single-sign-on token of the currently logged-in ISsoTokenInfo
user
Settings TrendDuration Gets or sets the length of a trend duration in minutes integer
GridLines Shows or hides grid lines on a pen trend boolean
PVVisible Shows or hides the process value of a Situational boolean
Awareness Library symbol
PVOptimalRangeVisible Shows or hides the optimal range indicator on a boolean
Situational Awareness Library symbol
PVOperatingAutoScale Enables or disables meter auto scaling on a Situational boolean
Awareness Library symbol
SPVisible Shows or hides a Setpoint on a Situational Awareness boolean
Library symbol
TrackerVisible Shows or hides a tracker line on the meter of a boolean
Situational Awareness Library symbol
LabelVisible Shows or hides the label on a Situational Awareness boolean
Library symbol
EngUnitsVisible Shows or hides the engineering units of a Situational boolean
Awareness Library symbol
ControllerOPVisible Shows or hides the Controller Output for a Situational boolean

40 InTouch OMI SDK Help


InTouch OMI SDK Help

Attribute Attribute Name Description Data Type


Category
Awareness Library symbol
AlarmIndicatorVisible Shows or hides an alarm indicator on a Situational boolean
Awareness Library symbol
ControllerOPCmdVisible Shows or hides the Output Command for a Situational boolean
Awareness Library symbols
ChartRangeIncrement Sets the precision of the incremental range of chart integer
values shown as measurement lines of Situational
Awareness Library Dashboard symbols
SafetyVisible Shows or hides a safety indicator on a Situational boolean
Awareness Library symbol
EnableDisableSound Enables or disables alarm sounds boolean
ShowControlLinks Shows or hides the control links of a Situational boolean
Awareness Library symbol
ShowToolTips Shows or hides the tooltips of a graphic boolean
ToggleSPTag Toggles between a Setpoint or tagname value on a boolean
Situational Awareness Library symbol
DisableHorn Enable or disable an external alarm horn boolean
AckAll Enable or disable the acknowledgement of all alarms boolean
PenTrendVisible Shows or hides all pen trend lines of a trend symbol boolean
System Millisecond Gets the millisecond number, for example "801" integer
Second Gets the second number, for example "48" integer
Minute Gets the minute number, for example, "50" integer
Hour Gets the hour number, for example "20" integer
Day Gets the day number, for example, "12" integer
Month Gets the month number, for example, "1" integer
Year Gets the year number, for example, "2017" integer
Date Gets the date, for example, "17178" DateTime
Time Gets the time, for example "75048801" DateTime
DateTime Gets the date and time, for example "17178.868" DateTime
DateString Gets the date, for example "1/12/2017" string
TimeString Gets the time, for example, "8:50:48" string

Web Control SDK


The WebControl SDK exposes the WebControl assembly (ArchestrA.Client.WebControl.dll) and namespace. It
provides a Chromium-based browser, and lets you connect to SharePoint sites, web sites, and apps that use web
content, such as the MapApp. Content is made available on the basis of the logged-in user's credentials.
This assembly includes the WebControl Base class, which provides browser capabilities. An app can derive from this
class and add custom behaviors.

41 InTouch OMI SDK Help


InTouch OMI SDK Help

Creating Your First InTouch OMI App


Each of the component SDKs of the InTouch OMI SDK include a sample app that demonstrates the capabilities of the
component SDK. This section of the documentation outlines the concepts and process for building an application.
Most of the code snippets in this section are taken from the various sample applications.
The InTouch OMI SDK uses Visual Studio as a development environment. Before beginning, add the InTouch OMI
assemblies and sample applications to TFS source control. Use Visual Studio to write your application, using one of
the supported languages (C#, C++, or Visual Basic). You can extract code from any of the sample apps included with
the SDK, or use an app as a starting point and modify it as needed.

Sample Apps
The code for several sample apps is included with the SDK assemblies, and reside under the folder: C:\Program Files
(x86)\ArchestrA\Framework\AcfSdk\Samples. The sample apps are:
ContentPresenterApp: Shows graphic items from one or more selected nodes of a ViewApp navigation
model.
DocViewerApp: Provides a PDF and text file viewer. This app uses the AppConfig SDK and illustrates how to
build an app editor.
HamburgerApp: Controls the movement of a selected layout slide-in pane. During run time, the
HamburgerApp appears as a button consisting of three parallel horizontal lines.
NavBreadcrumb: Shows a user-selected sequential path through ViewApp navigation model.
NavCommon: Provides the common set of references used by the NavTree and NavBreadcrumb apps.
NavTree: Shows a hierarchical arrangement of parent and child navigation items that together represent a
ViewApp navigation model.
WebBrowserApp: Shows a full-featured, Chromium-based web browser that supports WPF apps.
Before you begin writing your own apps, we recommend that you examine these apps. To view the sample code, use
Visual Studio to open the SDKSamples.sln solution file, located in the Samples folder. Each app uses InTouch OMI
component SDKs and are commented. Use the apps as models as you build your own applications.

Create a New Project


Prerequisites
The following software must be installed on your system:
Application Server IDE 2017 Update 1
Visual Studio 2013 or higher

Initial Setup
1. In Visual Studio, create a new project.
2. Select a supported language: Visual Basic, C#, or C++.
3. Select Windows Desktop.
4. Select either WPF User Control Library or WPF Custom Control Library and press OK.
5. Select .NET Framework 4.5.1.
6. Enter a name for your new application.

42 InTouch OMI SDK Help


InTouch OMI SDK Help

Note: We recommend that you start with WPF User Control Library to create your user controls, as this may be
a simpler starting point. However, if you are comfortable creating custom controls, feel free to use the WPF
Custom Control Library.

Build the App UI


Structure the UI for your app as needed for the framework elements you will use and the business logic you will
create. For your UI, you will probably want to specify foreground and background colors, the structure type (for
example, Grid or StackPanel), dimensions, static text, etc. Modify the xaml file as needed for your UI.
You can use WPF (Windows Presentation Framework) or WinForms as the front end framework of your application.
However, if you use WinForms controls, they must still be hosted in WPF in order to use them in an InTouch OMI app.
Since foreground color, background color, and text size are UserControl FrameWork element properties, there is no
reason to define these. Whenever possible, leverage the properties that already exist in the FrameWork and the
InTouch OMI assemblies with which you are working. In the example code, since StackPanel is a child element of
UserControl, we can use binding to set foreground/background colors and text size.
As the example code shows, the default Grid element has been changed to a StackPanel element, and a textbox has
been added to displays static text. The UserControl has been renamed as a child element of "MyOMIApp." A pointer
has been added within the UserControl definition (x:Name="MyUserControl"), and binding to this pointer is used to set
the background color for the StackPanel. Similarly, binding is used to set the foreground color, background color, and
font size for the TextBox in the StackPanel. You can then set the properties of these design elements in the cs file,
along with the business logic.
To filter which controls are visible to the user, you can add an AppManifest.xml file to filter what users will see when

43 InTouch OMI SDK Help


InTouch OMI SDK Help
they configure your app in the IDE.

UserControl1.xaml
<UserControl x:Class="MyOMIApp.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" x:Name="MyUserControl">
<StackPanel Background="{Binding Background, ElementName=MyUserControl}">
<TextBox Text="Welcome to My OMI Navigation Display App" Foreground="{Binding
Foreground, ElementName=MyUserControl}" FontSize="{Binding Fontsize,
ElementName=MyUserControl}"></TextBox>
</StackPanel>
</UserControl>

The design view of the control shows the static text in a textbox enclosed within the StackPanel.

Build Your Business Logic


Build the logic in your app to solve a business problem. As there are many ways to achieve a particular result, use the
methods that you are most familiar with
Let's say you want to build an app that gets property-change notifications. Among the tasks that need to be done are:
Create a simple property to get change event notifications from the SDK
Add a reference to the appropriate SDK namespace (for example, ArchestrA.Client.MyViewApp.Navigation)
Specify which property your are interested in (for example,
ArchestrA.Client.MyViewApp.Navigation.CurrentAssetName)
Determine if the ViewApp is functioning in run time or is being configured. If it is being configured, we are
not interested in receiving notification

44 InTouch OMI SDK Help


InTouch OMI SDK Help
Establish a reference to the SDK to get change notification

CurrentAsset Changed Notification


namespace MyOMIApp
{
/// <summary>
/// Interaction logic for UserControl1.xaml
/// </summary>
public partial class UserControl1 : UserControl, INotifyPropertyChanged
{
/// <summary>
/// this is a constructor
/// </summary>
public UserControl1()
{
InitializeComponent();

/// if this control is in design mode, don't do anything


if(!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))

/// if not in design mode, subscribe


ArchestrA.Client.MyViewApp.Navigation.PropertyChanged +-
Navigation_PropertyChanged;
}
/// simple property - get asset change notification from SDK; need to get
reference from SDK
public string CurrentAssetName { get; set; }
/// <summary>
/// setting up business logic
/// </summary>

void Navigation_PropertyChanged(object sender,


System.ComponentModel.PropertyChangedEventArgs e)
{
if (Incontext)
{
if (e.PropertyName == CurrentAsset)
{
CurrentAssetName =
ArchestrA.Client.MyViewApp.Navigation.CurrentAsset;
if (PropertyChanged != null)
PropertyChanged(this, new
PropertyChangedEventsArgs("CurrentAssetName"));
}
}
}
/// Create a simple property to get notification from SDK
/// use browsable(false) so this is not imported
[Browsable(false)]
public string CurrentAssetName { get; set; }
public bool Incontext { get; set; }

AppManifest.xml File
Public classes are automatically exposed in your app as controls. Properties of these controls are similarly exposed.
When your app is imported into the System Platform IDE and selected by a user in the Layout and ViewApp Editors,

45 InTouch OMI SDK Help


InTouch OMI SDK Help
the controls and properties will be visible. An app will include at least one public Framework element. If your
assembly contains dependencies (for example, third-party UI DLLs), an app can easily include dozens or even
hundreds of controls and properties for UI or other functions ancillary to the business controls you have built. To
avoid the confusion that this will cause for your app consumers, you can limit which controls and properties are
shown by adding an AppManifest.xml file to your project. The manifest file acts as a filter and limits what the user
sees. Only the controls and properties that are explicitly listed in your AppManifest.xml file will be visible to users.
If your app includes an editor, the AppManifest file is required to expose the editor. Information about the syntax for
showing an app editor are listed below.

For each control you wish to expose for use, list any configurable properties that should be visible. A control does not
have to have configurable properties.
If no AppManifest.xml file is included, all controls and properties for each control, including those in
dependent files, will be exposed.
If an AppManifest.xml file is included that does not explicitly include controls, no controls or properties will
be exposed.
If your app includes an app editor, the AppManifest.xml file is required. If not, the AppManifest.xml file is
optional.
The AppManifest.xml file must specify the assembly name, control name(s), and configurable properties (if any) for
each control. The control name (ControlFullName) is the public class name, and is prefaced by the assembly name
(separated by a period (dot)). The structure of the AppManifest.xml file is as follows:

AppManifest Structure
<Filters>
<Control AssemblyName="ArchestrA.Apps.MyOMIApp"
ControlFullName="ArchestrA.Apps.MyOMIApp.MyControl">
<PropertyName="Configurable Property 1" />
<PropertyName="Configurable Property 2" />
<PropertyName="Configurable Property 3" />
</Control>
</Filters>
<Editor EditorFullName="ArchestrA.Apps.MyOMIApp.Editor.OMIEditor"
AssemblyName="ArchestrA.Apps.MyOMIApp.Editor">
</Editor>

Note that the EditorFile name is the AssemblyName with a "dll" suffix. The EditorFullName is the fully qualified name
of the class that implements the editor.

46 InTouch OMI SDK Help


InTouch OMI SDK Help

Example AppManifest.xml
<?xml version="1.0"?>
<AppManifest AppVersion="1.0.0">
<Filters>
<!--List all the Controls that need to be exposed to the ArchestrA IDE user to
utilize them in a View Application.
Only the controls listed here will be available for the IDE users to place them on
panes within a Layout or a ViewApp.-->
<Control AssemblyName="ArchestrA.Apps.SampleApp"
ControlFullName="ArchestrA.Apps.SampleApp.MyControl1A">
<!--List the public properties on this control that need to be exposed when user
is configuring this control in a Layout or
a ViewApp. The Property Editor within the Layout Editor and ViewApp Editor
includes these properties when this control is
selected and allows the user configure new default values.-->
<Property Name="InContext" />
<Property Name="Configuration" />
<Control AssemblyName="ArchestrA.Apps.SampleApp"
ControlFullName="ArchestrA.Apps.SampleApp.MyControl2B>
<Property Name="InContext" />
<Property Name="FontSize" />
<Property Name="Background" />
<Property Name="Foreground" />
</Control>
</Filters>
<!--If this app has an editor to edit its settings, provide the editor class and
assembly.
If there is no App Editor, leave the editor xml element empty.-->
<Editor EditorFullName="ArchestrA.Apps.SampleApp.Editor.SettingsEditor"
AssemblyName="ArchestrA.Apps.SampleApp.Editor">
<!--List any files that are only needed by the App Editor in the IDE node. These
files are available only on the IDE node,
and are not deployed to the run-time node.-->
<EditorFile Name="ArchestrA.Apps.SampleApp.Editor.dll />
</Editor>
</AppManifest>

Global App Editor


For some apps, users may want to have multiple instances of the app running in a ViewApp. For example, users may
want to have multiple instances of the MapApp running in a single ViewApp. You can provide your users with a
method that can configure all instances of your app. The AppConfig SDK is used to write an editor that is bundled
with an app, and that can globally configure the app. The AppConfig SDK includes the following framework elements:
A common container that can host the editor(s) for configuring properties globally.
An option to register commands for display on the command bar.
An option to have multiple tabs for configuration.
All common ArchestrA object functionality, including:
App import/export
Data persistence
Check-in/-out
Override check-out

47 InTouch OMI SDK Help


InTouch OMI SDK Help
Rename
Delete
Open as read-only
The AppConfig SDK lets you add one or more editors to your app and give it a name. If multiple editors are used, they
are displayed as tabbed controls, and each control can be named as needed. The editor(s) allow users to:
Save a configuration within the app.
Load the saved configuration.
Once you have created your editor(s), you must expose the editor(s) through the AppManifest.xml file.
See AppManifest.xml File for additional information.

App Editor Configuration


The AppConfig SDK lets you configure all areas of an editor, including the command bar and the main area. You will
have to define three things as you build your editor:
View:: This is the area below the title bar and is the main window of the editor.
The contents of the view: Also referred to as the activity, the contents define the UI, how configuration
data is saved to an app object, and how the data is loaded to the app at run time. An editor always
contains at least one activity (main activity editor). If your app editor defines multiple activities, you will
add activity tabs that appear in the title bar, above the view.
The activity tab(s): The activity tab defines data sources, the UI, and the configuration page. Each activity
tab is independent within the editor. Thus, if your editor has multiple activities, each one is an
independent editor that defines different aspects of your app.

Activities
The AppConfig framework provides the core capabilities for your editor (activity), and provides the ability to save
and close an app, to launch a window, etc. Each activity needs to know what information has to be saved in the app
and what information gets loaded into the app at run time. Configuration information is saved into the app object
itself (within the IDE), and then at run time, the configuration information is extracted from the app object and
uploaded to the run time app. When a configuration change is detected (object is dirty), the save, save and close,
and close options will be enabled within the title bar. You will have to define the file name, file format (for
example, json, xml, text file, etc.), and file location for saving the configuration information.
Keep in mind that an app editor can encompass multiple editors (activities). You can choose have each activity
create its own configuration file, or use a single configuration for all activities. The following sample illustrates how
to implement load and save in the main activity:

Implement Load and Save


public class MyInTouchOMIAppConfigEditor : IEditorConfig
{

public void InitializeEditor(IEditorBase editor)


{
this.editor = editor;
this.mainActivity = new MyInTouchOMIAppMainActivityViewModel(this.editor);
}
public IEnumerable<IEditorActivity> GetActivities()
{
return new IEditorActivity[] { this.MainActivity };
}
public void Load(Dictionary<string, byte[]> appData)
{
this.mainActivity.Load(appData);
}

48 InTouch OMI SDK Help


InTouch OMI SDK Help
public Dictionary<string, byte[]> Save()
{
return this.mainActivity.Save();
}
}

EditorActivityViewModelBase
You will also have to implement the EditorActivityViewModelBase class. Your main activity is derived from this class.
If you are implementing multiple activities, use the Label property to add tabs on the title bar for each activity.

Label Property
public virtual string Label
{
get { return Properties._string.Label;
}

You can customize Views and View Models as needed within your editor. You will need to add one View Model and
View for each activity, on a one to one to one basis. Only one instance of an editor that defines the App Editor UI is
required to contain all activities, Views, and View Models. You can associate the View and View Model within the
WPF framework; there are many options for doing this association. For example, to define a View Model:

Generic.xaml
<DataTemplate DataType="{x:Type omiAppEditor:EditorMainActivityViewModel}">
<view:AppEditorView />
</DataTemplate>

Read-Only Mode
The framework also exposes the read-only mode, but you must add this to your editor. You will have to add code get
the status of the app object from the UI and disable the UI in your editor if the app object is opened as read-only.
Use the isReadOnly property, which gets a value that indicates whether or not object is in IsReadOnly state.

IsReadOnly
public virtual bool IsReadOnly { get; private set; }

AppManifest.xml File
The AppManifest.xml file is a requirement if you are adding an editor for your app. See AppManifest.xml File for
additional information about this file. You must define two items in the AppManifest file:
AssemblyName: This is the same as the namespace (name of the dll, minus the dll extension).
EditorFullName: This is the fully qualified class name of the type that implements the IEditorConfig
interface. It is the namespace plus the name of the control.

AppManifest.xml
<AppManifest>
<Filters>
</Filters>
<Editor AssemblyName="ArchestrA.Visualization.MyOMIAppEditor"
EditorFullName="ArchestrA.Visualization.MyOMIAppEditor.MyOMIConfigEditor">
</Editor>
</AppManifest>

49 InTouch OMI SDK Help


InTouch OMI SDK Help
IEditorActivity
The basic framework commands are save, save/close, and close. To implement additional commands, use
RegisterCommands() method from the IEditorActivity interface. This editor also contains the CanCloseEditor() method
(this method is also available in IEditorViewModelBase). You may want to add commands for validations based on
business logic, such as checking if a user has entered a valid URL syntax, and block saving or closing the editor if the
property does not validate.

IEditorActivity Methods
public virtual void RegisterCommands()
{
ResourceDictionary icons = new ResourceDictionary() { Source =
GetResourceUri((typeof(SampleActivity).Assembly), "Resources/Icons.xaml") );
DrawingBrush comIcon1 = icons[
public virtual bool CanCloseEditor()
{
return true;
}

Using Security
You can add security to your app by adding a secure login capability. The following code sample outlines how to do
this.

SecureLoginSampleApp
namespace SecureLoginSampleApp
{
using MyViewApp = ArchestrA.Client.MyViewApp;
/// <summary>
/// Interaction logic for SecureLoginViewSample.xaml
/// </summary>
public partial class SecureLoginViewSample : UserControl
{
public SecureLoginViewSample()
{
InitializeComponent();
this.Loaded += SecuritySampleApp_Loaded;
}
private void SecuritySampleApp_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = new SecureLoginSampleVM();
SecureLoginSampleVM vm = this.DataContext as SecureLoginSampleVM;
if (vm != null)
{
vm.Initialize();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
MyViewApp.Security.ShowLoginDialog();
}
private void Logout_Click(object sender, RoutedEventArgs e)
{
MyViewApp.Security.Logout();
}
}
}

50 InTouch OMI SDK Help


InTouch OMI SDK Help

Troubleshooting
Add a Link to the Logger
Debug a Running App
Debug an Initializing App

Add a Link to the Logger


The InTouch OMI SDK includes a logger that you can add to your app to aid in app development and troubleshooting.
The logger contains a number of methods, including LogError, LogInfo, LogWarning, LogTrace, LogEntry, etc. To add
the logger:
1. In the Visual Studio Solution Explorer, select your app.
2. Right-click and select Add > Existing Item (or press Shift + Alt + A).
3. Navigate to the AcfSdk\Includes folder.
4. Select the Logger.cs file.
5. Click the down arrow on the Add button
6. Click Add As Link.

Debug a Running App


Use the following steps to debug an app that is running, but is exhibiting unexpected behavior when you execute an
action within the app. Examples include pressing a button or expanding a navigation node in the ViewApp and not
getting the expected result.
1. Deploy your app.
2. In Visual Studio, build your project in Debug mode.
3. After the project builds, go to the output folder and copy both the pdb file and the debug version of the dll
file.
4. Place both files in the app location for your Galaxy, in the applicable folder under Controls. For example:
C:\Program Files (x86)\ArchestrA\Framework\FileRepository\<GalaxyName>\ObjectFileStorage\
<$ViewApp_Name>\Deployed_1051\Controls\<MyApp>
You will be overwriting the original dll file and adding the pdb file to the app folder.
5. Launch the app from the Wonderware Application Manager.
6. Go to your project in Visual Studio, and select the debug process.
7. Select View.exe and attach to the debug process.
8. Add a breakpoint at the point the problem is occurring.
9. When you hit the breakpoint, inspect the values and step through the code until you find the problem.

Debug an App that Does Not Initialize


Use the following steps to debug an app that does not initialize.
1. Deploy the ViewApp.
2. Go to the app properties in Visual Studio.
3. Go to the debug section.
4. Select "Start external program" and select the deployed ViewApp (View.exe).
5. Select Save and start debug.

51 InTouch OMI SDK Help


InTouch OMI SDK Help
6. Launch View.exe from the Wonderware Application Manager.
7. Add a breakpoint, then step through the initialization of the app until you find the problem.

Redistributing Your Application


Import and Test Your App into the IDE
Once you have completed writing and compiling your app, you can import the assembly into the System Platform IDE.
If your assembly has dependencies, or consists of multiple DLLs, move all the DLL files into a single folder. Dependent
files can be moved into subfolders for organizational purposes, but this is not a requirement for InTouch OMI. When
importing an app, InTouch OMI takes the files in the parent folder and any subfolders.
Once you have imported your app, you can incorporate minor changes that do not change the shape of the app
(add/delete controls or properties) by simply copying over the dll file, instead of re-importing it. This can help to
speed up the development and troubleshooting processes. If you need to re-import your app, delete the old version
in the IDE before importing the app again.

To Import an App
1. Assemble the App, together with all required dependencies and related files, into a folder.
2. Select Import from the Galaxy menu.
3. Select ArchestrA App.
4. Select the folder that contains the App to be imported. The contained App, along with all dependent files,
including dependent files contained in subfolders, are imported when you select OK.

5. The app appears as a new object in the GraphicToolbox when the import successfully completes named
"DisplayModule_00n," where n is 1 or the next available integer. Rename the app as needed.
The new app object can be moved to another folder in the Graphic Toolbox, deleted, or exported as an
.aaPKG file for use in another Galaxy.

To Test an App

52 InTouch OMI SDK Help


InTouch OMI SDK Help

1. Test your app by adding it to a layout and using the layout in a ViewApp.
2. When you add the app to a layout, its public properties should be visible for configuration. If you have added
an AppManifest.xml file, you should see only the public properties that are listed in the AppManifest.xml.
3. Deploy the ViewApp and open it with the Wonderware Application Manger to verify the operation of the
app in run time.

Export Your App


After you have imported your app into the IDE, use the export function to bundle the app as a reusable object in an
aaPKG (package) file. Others can import your package file into their Galaxies. The package file, when imported into
a Galaxy, will load the app into the Graphic Toolbox. See the Application Server User Guide, "Export Objects," for
additional information.

API References
The InTouch OMI SDK provides programmatic access to its component SDK assemblies and namespaces. Use the
methods and parameters that these provide to build your own InTouch OMI custom applications that can users can
configure for their ViewApps.

53 InTouch OMI SDK Help


InTouch OMI SDK Help

54 InTouch OMI SDK Help

S-ar putea să vă placă și