LNS® Plug-in Programmer’s Guide Release 4 ® 078-0393-01A
Echelon, LON, LonWorks, Neuron, 3120, 3150, Digital Home, i.LON, LNS, LonMaker, LonMark, LonPoint, LonTalk, NodeBuilder, ShortStack, and the Echelon logo are trademarks of Echelon Corporation registered in the United States and other countries. FTXL, LonScanner, LonSupport, ISI, OpenLDV, and LNS Powered by Echelon are trademarks of Echelon Corporation. Other brand and product names are trademarks or registered trademarks of their respective holders.
Table of Contents Preface .................................................................................................... vi Purpose ..........................................................................................................vii Audience.........................................................................................................vii Software Requirements ..................................................................................vii Content ...............................
Appendix F Running the ACME Example C# Plug-in........................
Preface You can use LNS device plug-ins to simplify the installation of your devices for network integrators. This manual provides an overview of the LNS Plug-in API and how plug-ins and director applications such as the LonMaker Integration Tool interact. It describes how to install the LNS Plug-in Framework Developer’s Kit, which implements the LNS Plug-in API and provides a set of framework assemblies that let you efficiently develop and redistribute LNS plug-ins.
Purpose This document describes how to write LNS plug-ins using .NET programming languages such as C# and Visual Basic .NET. After reading this document, you should understand the basic mechanics of how plug-ins work, and how to write a plug-in using the LNS Plug-in Framework. Audience Users of this document should have a basic understanding of the LNS Object Server, and experience programming in C#, Visual Basic .NET, or another .NET programming language.
LNS®Programmer’s Guide Describes how to use the LNS Object Server ActiveX Control to develop an LNS application on a Microsoft Windows Vista™, Server 2003, Windows XP, or Windows 2000 host computer. LonMaker® User’s Guide Describes how to use the LonMaker Integration Tool to design, commission, modify, and maintain LONWORKS networks. Other Related Material This document refers to and describes the LNS Plug-in API that all plug-ins use.
Region Europe Languages Supported English German French Italian Contact Information Echelon Europe Ltd. Suite 12 Building 6 Croxley Green Business Park Hatters Lane Watford Hertfordshire WD18 8YH United Kingdom Phone: +44 (0)1923 430200 Fax: +44 (0)1923 430300 lonsupport@echelon.co.uk Japan Japanese Echelon Japan Holland Hills Mori Tower, 18F 5-11-2 Toranomon, Minato-ku Tokyo 105-0001 Japan Phone: +81-3-5733-3320 Fax: +81-3-5733-3321 lonsupport@echelon.co.
1 Introduction This chapter describes the types of plug-ins that are used with LONWORKS networks, and it describes how director applications request actions from plug-ins. It explains how the LNS Plug-in Framework allows plug-ins to function in the .NET environment and interface with director applications.
Introduction An LNS plug-in is an out-of-process automation server that implements the COM-based LNS Plug-in API so that it may be instantiated and controlled by an LNS plug-in director application. Plug-ins provide a standard way to extend and customize the functionality of LNS applications.
configuration properties and enforce limits on configuration property values. You can create a device plug-in executable that operates on multiple device types. The single executable that is able to operate on multiple device types is a programming convenience.
• A simple out-of-process server task model that supports plug-ins in the .NET environment (LNS plug-ins are out-of-process COM servers, for which support in the .NET environment is not well documented). The LNS .NET wrapper is the Primary Interop Assembly, which is generated by Echelon and distributed with LNS. It provides a Run-time Callable Wrapper (RCW) that allows your .NET plug-in to interface with the COM-based LNS API. Note that the LNS .NET wrapper is required for plug-in development with .
2 Creating and Redistributing LNS Device Plug-ins This chapter explains how to create an LNS device plug-in using the LNS Plug-in Framework Developer’s Kit, how to debug your plug-ins, and how to create an installation project for your plug-in so that you can provide it to users.
Creating and Redistributing Plug-ins Overview You can use the LNS Plug-in Framework Developer’s Kit to create an LNS device plug-in and create an installation project for your plug-in so that you can provide it to users. To create a new plug-in, you need to first install the Microsoft .NET Framework Version 2.0 Redistributable Package. You then need to install the LNS Plug-in Framework Developer’s Kit and an LNS Turbo plug-in director application such as the LonMaker Tool Turbo Edition (3.
5. • The ObjectServer folder is common to all computers with the LNS Server runtime installed. • The Assemblies folder contains the .NET assemblies referenced by plug-ins that are built using the framework. Visual Studio is informed of this directory by a registry entry added during the installation. This makes the assembly information accessible to the development environment. These assemblies are also installed directly into the Global Assembly Cache for runtime support of framework-based plug-ins.
Creating the Plug-in Project You can create a C# or VB.NET plug-in project using Microsoft Visual Studio 2005 (or later) following these steps (note that the example shown in this section is a C# plug-in project created with Microsoft Visual Studio 2005 Professional Edition): 1. Create a new C# or Visual Basic Windows Application project. The project must create an EXE target. Specify a name and location for your project. Click OK. 2. Click Project and then click your application’s Properties option.
• In the Default namespace property, change the namespace to .. • In the Assembly name property, enter a unique and descriptive assembly name that matches your selected namespace (for example, ..). • In the Output type property, verify that Windows Application is specified. • In the Icon property under the Resources box, specify an icon. 4. Click Assembly Information. The Assembly Information dialog opens. 5.
7. Copy the PostBuild.bat file from the LonWorks\ObjectServer\Examples\PluginFramework\ExampleCSPlugin to your project folder. 8. In the Post-build event command line property, enter the following line: Call "$(ProjectDir)PostBuild.bat" "$(TargetPath)" The PostBuild.bat file will carry out the post-build actions necessary to register your plug-in during the development process.
13. Select the Echelon.LNS.Interop and the Echelon.LNS.Plugin.Framework .NET assemblies, and then click OK. • • Echelon.LNS.Interop enables your application to interact with LNS. Echelon.LNS.Plugin.Framework provides the base functionality for your plug-in. Creating the Plug-in Source Files After you create your LNS plug-in project, you need to create the plug-in source files.
Implementing the Plug-in Server Class To implement your plug-in server class, modify the source as follows: 1. Add using System.Runtime.InteropServices and using Echelon.LNS.Plugin directives. 2. Add a ComVisible(false) attribute to the class. You will not need to create this class directly from COM clients. 3. Derive your plug-in server class from the PluginServerBase base class (located in the Echelon.LNS.Plugin namespace). 4.
5. Add a PluginInfo public static property that returns a reference to a PluginInfo object that describes your plug-in. For efficiency, you should return a reference to a previously created read-only object (for example, using a statically initialized field) instead of creating a new instance each time. The PluginInfo object provides the registration information for the plug-in that will be written to the Windows registry for access by directors.
Field Description MultiObject Indicates to a director whether the plug-in supports MultiObject functionality. When supported, the MultiObject functionality allows the plug-in to cache multiple SendCommand() method invocations from a director and to defer the execution of those requests until told to do so by the director. If the MultiObject field is set to Feature.
Field Description Prelaunch Indicates to a director whether the director may launch the plug-in in the background before the plug-in is needed. Supporting this property can improve the perceived startup performance of your plug-in, as the plug-in can open the specified network and perform any required initialization before receiving the information from the director when the director decides to invoke a command that the plug-in supports.
Field Description Scope A ComponentAppScope value identifying the scope of the plug-in’s command. This is known as the command scope, which should not to be confused with the registration scope or plug-in scope (see the Glossary in Appenidx E for details).
"Tests device.", EnumCommandIds.Test, EnumClassIds.AppDevice, false, ComponentAppScope.System // // // // // Description CommandId ComponentClassId DefaultAppFlag Scope ) // TODO: add additional commands here }; public override PluginCommand[] PluginCommands { get { return _PluginCommands; } } // constructor public MyPluginObject() { // create and ‘register’ the plug-in user interface PluginForm = new MyPluginForm(); PluginForm.
Field Description ObjectName The fully specified name of the LNS object on which to perform the command, as specified by the director. LcaObject A reference to the LNS object on which to perform the command, as decoded by the LNS Plug-in Framework (or null if unable to decode). Note: The Actions array will contain only one item unless the plug-in MultiObject feature is specified as Supported. You can also obtain a reference to the LNS Object Server through the framework’s LcaClass.
Registering DeviceTemplate and LonMarkObject Scoped Plug-in Commands The LNS Plug-in Framework does not currently support registration of DeviceTemplate and LonMarkObject scoped plug-in commands; however commands at one or both of these scopes are essential to device plug-ins. You can override the framework function and implement registration of DeviceTemplate and LonMarkObject scoped plug-in commands by following these steps: 1. Set your plug-in command’s PluginCommand.Scope property to ComponentAppScope.
Redistributing your Plug-in After you have developed and tested your plug-in, you can create an installation project for it so that you can distribute your application to your users. See the documentation for your selected installer for details on how to do this. You should adhere to the following guidelines when creating an LNS plug-in installer based on the framework: • A plug-in based on the LNS Plug-in Framework requires Microsoft .NET Framework 2.0 (or newer) to be installed.
3 How Plug-ins Work with Directors This chapter details how directors and plug-ins interact. Once you understand the basic interaction between directors and plug-ins, using the LNS Plug-in Framework will be straightforward.
How Plug-ins Are Represented in the LNS Object Server The LNS network database represents physical objects on a LONWORKS network with objects in the database. For example, network databases contain Router, Channel and AppDevice objects. The LNS Object Server represents a plug-in and its functionality through ComponentApp objects. There is one ComponentApp object for each action that a plug-in implements and one ComponentApp object for the plug-in itself that is used to register the plug-in.
computer while checking to make sure that it does not overwrite newer versions. Next, the setup program adds a number of items to the Windows registry. Some of these items are required because plug-ins are implemented as COM servers. Other entries are required by LNS. LNS requires that a plug-in store registration data for itself in the Windows registry (see Implementing the Plug-in Object Class in Chapter 2 for more information).
1. The plug-in fetches the appropriate ComponentApps collection, based on the scope of the action. If the scope of the action is device or functional-block specific (for example, the action will be added to a DeviceTemplate’s ComponentApps collection or a DeviceTemplate.LonMarkObject’s ComponentApps collection), you may need to create a DeviceTemplate before you can add the ComponentApp object. To see if the system already contains a device template for your device type, use the DeviceTemplates.
The plug-in does not need to register its registration command; the director will automatically add the registration command by adding a ComponentApp object at the appropriate scope with a command ID of LcaCommandRegister (50) if the plug-in is successfully registered. Note that directors use this ComponentApp object differently than the ComponentApp objects created by plug-ins.
Director Action Plug-in Response requests. The Plug-in Framework automatically manages the plug-in’s reference counts. See How Plug-ins Know When To Exit later in this chapter for more information on how reference counts are tracked. If this is a remote client, sets the RemoteFlag property to True and then sets the NetworkInterfaceName property to identify the interface that the plug-in should use to communicate with the LNS Object Server. All plug-ins must support these properties.
Director Action Plug-in Response Releases the instance of the plug-in it created. COM decrements the plug-in’s usage count. If this is the last user of the plug-in and the plug-in is not visible (for example, the Visible property is False), the plug-in’s destructor is called and the server exits. How Directors Support Prelaunch The pre-launch feature allows a plug-in to initialize and open the network when the director is started.
5. If the plug-in has not set the MultiObject value in the Windows registry to 1, release the reference to it. SingleInstance functionality is described in Implementing the Plug-in Object Class in Chapter 2. The director holds a reference to the plug-in so that it can send additional objects (in the case of MultiObject support) or can activate the existing instance (in the case of SingleInstance support).
How Directors Pass Object Names The objectName parameter of the SendCommand() method specifies the location of the target object in the LNS object hierarchy. The name includes any qualification required to find the appropriate object in the hierarchy.
with the (now terminated) plug-in will result in exceptions in the directors. The desired behavior would be for the plug-in to become invisible (instead of exiting) when the user clicked the exit button and to delay exiting until the last director released its reference to the plug-in. The overlap can also be in the other direction. A plug-in might not be visible when the last director releases its reference to it. Some plug-ins might be designed to always run in the background, without a user-interface.
After creating an instance of a plug-in, the director can set any property at any time, with the exception that the NetworkInterfaceName property, which if set, must be set before the NetworkName property. Uninstallation Issues Your plug-in should implement the LcaCommandUnregister (51) command for LNS network databases in order to allow de-registration of plug-in function from individual network databases, while still providing the plug-in functionality on the computer.
Appendix A Standard Plug-in Commands This appendix lists the standard commands that may be implemented by plug-ins. Plug-ins may also implement manufacturer-specific commands.
The following table lists the standard LNS plug-in commands. Command Description LcaCommandBrowse 20 Monitor and control the object. LcaCommandBuildImage 10 Build the image for the object. Only applies to AppDevice class objects. LcaCommandCalibrate 14 Set calibration configuration properties for an object. LcaCommandCommission 11 Load the network image into an object. Only applies to AppDevice class objects. LcaCommandConfigure 13 Set the configuration properties for an object.
Appendix B Standard Plug-in Properties This appendix lists the standard properties that must be implemented by plug-ins, as well as optional properties that may also be implemented by plug-ins. Plug-ins may also implement manufacturer-specific properties.
The following table lists the standard LNS plug-in properties. Note that the property names CharacterEncoding and LanguageId are reserved for future use. Name Type Description Height Long The height, in pixels, of the plug-in’s main window. LcaVersion Read-Only String Minimum version of the LNS Server redistribution required by this plug-in. Left Long The x location, in pixels, of the upper left corner of the plug-in’s main window. 0 is at the leftmost of the user’s display.
Name Type Description Batch Read-Write Long The optional Batch property allows plug-ins that support the MultiObject feature to cache incoming requests from directors and defer the execution of those requests until told to do so by the director. This is known as a batch operation.
Name Type Description Prelaunch Long The optional Prelaunch property allows a director to launch the plug-in in the background, typically when the director is started. Not all directors support the use of pre-launch, and if not this property is ignored, and the plug-in would never be pre-launched by that director.
Name Type Description Version Read-Only String Version number of the plug-in. The version number is in “.” format. The minor release can contain either one or two digits. If it contains only one digit, it is assumed that the second digit is a zero. This means that "3.5" is assumed to mean "3.50". The version number may be followed with a space, and then optional text information. For example: “1.01 Controller Device Configuration Plug-in”.
Appendix C Standard Plug-in Object Classes This appendix lists the standard classes of objects that may be passed to plug-ins, as well as the addressing syntax used to identify objects.
The following table lists the standard LNS plug-in classes. Object Class ID Addressing Syntax LcaClassIdAppDevice 7 network/system.subsystem[.subsystem…]/appDevice LcaClassIdAppDevices 8 network/system.subsystem[.
Object Class LcaClassIdExtension ID Addressing Syntax 50 extension (for Object Server) network/extension network/system.subsystem[.subsystem…]/appDevice/extension network/system.subsystem[.subsystem…]/ LcaRouter:router/extension network/LcaChannel:channel/extension network/system/LcaDeviceTemplate:deviceTemplate/extension network/system/LcaHardwareTemplate:deviceTemplate/ extension LcaClassIdExtensions 51 n/a (for Object Server) network network/system.subsystem[.subsystem…]/appDevice network/system.
Object Class LcaClassIdNetworkInterfaces ID Addressing Syntax 15 network/LcaNetworkServiceDevice:networkServiceDevice network/system LcaClassIdNetworks LcaClassIdNetworkServiceDevice 2 n/a 40 network/LcaNetworkServiceDevice:networkServiceDevice network/system LcaClassIdNetworkServiceDevices 41 network LcaClassIdNetworkVariable 22 /networkVariable /LcaLonMarkObject:lonMarkObject/ networkVariable /LcaConnections:connections/networkVariable LcaClassIdNetworkVariableFi
Appendix D Standard Plug-in Exceptions This appendix lists the standard exceptions that may be thrown by plug-ins. Plug-ins may also throw manufacturer-specific exceptions.
The following table lists the standard LNS plug-in exceptions. Exception Code Description LcaComponentErrCantFindObject 20005 The plug-in could not locate the object specified by the ObjectName parameter. LcaComponentErrCantGetProperty 20007 An error occurred while the plug-in was attempting to get the property. LcaComponentErrCantSetProperty 20006 An error occurred while the plug-in was attempting to set the property. LcaComponentErrGeneric 20000 Some unspecified error occurred.
Appendix E Glossary This appendix provides definitions for key terms and concepts associated with plug-ins.
Glossary Action A command/object class pair implemented by a plug-in. A plug-in is defined by the actions that it can perform (for example, by the set of commands that it provides and by the class of objects that those commands operate on). For example, a plug-in might implement two actions, a test command of AppDevice class objects and a test command of Router class objects. COM A Windows standard for component-based software. COM defines a hierarchy of components, objects, and interfaces.
The items managed by LNS. LNS treats each network as a collection of objects. These objects include application devices, routers, connections, functional blocks, network variables, and the system. LNS Plug-in API The COM API used by LNS Plug-in directors to instantiate and command LNS plug-ins. LonMarkObject The type of LNS database object used to represent LonMark functional blocks. The LonMark terminology for this construct changed since LNS was introduced. Object See LNS Object.
The command scope of an action is indicated by the ComponentApps collection that the command is in. If an action is in the ObjectServer object’s ComponentApps collection, the action has object server-wide scope. If it is in a System object’s ComponentApps collection, the action has system-wide scope. If it is in a DeviceTemplate object’s ComponentApps collection, the action applies only to devices of that type.
Appendix F Running the ACME Example C# Plug-in This appendix describes the function of the ACME Example C# Plug-in provided with the LNS Plug-in Framework Developer’s Kit.
Running the ACME Example C# Plug-in After installing the LNS Plug-in Framework Developer’s Kit, the ACME Example C# Plug-in will be installed on your development computer in the same way as any LNS plug-in, which means that it will be visible to all director applications. As a result, you may want to unregister the ACME Example C# Plug-in to prevent networks that you create from registering the plug-in and popping up tracing message boxes.
3. Register the ACME Example C# Device Plug-in (Version 1.0) plug-in and observe register command calls. The following image shows a representative message box seen during the instantiation of the example plug-in. You must click the OK button in a timely fashion to allow normal plug-in operation, otherwise the director may time out waiting for the plug-in to respond. If you choose to Cancel the Plug-in API call instead, the director will be notified that the Plug-in API call has failed.
5. Observe the command calls that occur after selecting the describe device command. 6. The ACME Example Device Plug-in dialog opens and displays the results of the device description. 7. Execute the ACME Test Device command on a device in your network. To do this with the LonMaker tool, right-click the device, point to Plug-ins, and then click ACME C# (Test Device) on the shortcut menu. 8. Observe the command calls that occur after selecting the test device command. 9.
www.echelon.