An introduction to using plugins for customer-specific data protocols and analysis.
Plugin introduction
The Q.station X controller or Q.core firmware can be extended with non-standard functionality using a Plugin Management System.
-
No need to pack all functionality into one firmware package
-
Increases firmware stability of the core modules
-
No need for different firmware versions for different function packages
-
Standard firmware can be extended with custom functionality
-
Customers can develop and deploy their own plugin
-
Firmware extensions can be licensed
Advantages:
-
Plugins work as part of the firmware
-
No need to change the standard firmware
-
Easy to install via USB flash drive
-
Application programmable interface (XML-RPC)
Examples:
-
Customer-specific data protocols (serial, TCP/IP, UDP, …)
-
Special websites
-
Data analysis
-
Drivers
-
…
The Plugin Management System takes care of:
-
Installing and uninstalling the plugin
-
Plugin control (start/stop), also on state changes of Q.station's or Q.core's operation
-
Displaying plugin error, warning, and info messages in #actual.sta
-
Checking the plugin version to be sure that the used firmware APIs are compatible
The Plugin Management System has access to the device's internal resources:
-
Data interface: reading buffered data, read and write online data
-
Controller XML-RPC APIs (f.e. DiagnosticAPI, DataLoggerAPI, SummaryAPI, …)
-
Flash drives
In detail the Plugin Management System looks like this:
Plugin activation
The Plugin Management System functionality needs to be activated in the controller's configuration file (main_c.cfg).
[DEVICE]
PluginMode=1
Or via the test.commander software (version 1.80 or higher):
If debugging is required, the plugin mode has to be set to “debug” (PluginMode=2).
Plugin development
-
the plugin executable
-
an installation archive
Installation archive
-
{ProjName}.zip contains the plugin executable
-
{ProjName}_usb_install.zip contains {ProjName}.zip and an executable installation script
Installation script
-
The filename for the installation script is autorun.sh (in order to install from a USB flash drive automatically)
-
Variable ProjName
-
The Eclipse project name for the plugin project👉 It is also the name of the executable!
-
-
Variable PluginName
-
Name with which the plugin is registered
-
-
Parameter -clientport
-
XML-RPC port of Q.station X application (default is port no. 1200) or Q.core application (default is port no. 8090)
-
👉 Before running the installation script change to the directory where the script is installed!
Example:
Installation script for plugin QStationPluginExample_OnlineData. This plugin will be installed and registered with the name 'PluginExample_OnlineData':
#!/bin/sh
# Installation script for plugin
ProjName="QStationPluginExample_OnlineData"
PluginName="PluginExample_OnlineData"
mkdir -p /gins/fs/firmware/plugins
mkdir -p /gins/fs/firmware/plugins/${PluginName}
unzip $(dirname $0)/${ProjName}.zip -d /gins/fs/firmware/plugins/${PluginName}
chmod -R 700 /gins/fs/firmware/plugins/${PluginName}
cd /gins/fs/firmware/plugins/${PluginName}
./${ProjName} -install -clientport=1200 -name=${PluginName}
sync
👉 For Q.station with firmware version V2.12.x the part “/gins/fs/” in the directory name must be replaced with “/home/user1/fs/”.
Plugin installation
👉 In order to install and register a plugin the plugins need to be activated in the configuration (“activated” or “debug”)!
Installation using a USB flash drive
Installation using GI.monitor
Manual installation
-
Copy the installation archive {ProjName}_usb_install.zip to the device (for example to /gins/fs/online/hd0/).
-
Open a console (for example using PuTTY).
-
Unpack the installation archive
cd /gins/fs/online/hd0
unzip {ProjName}_usb_install.zip -
Execute the installation script
cd /gins/fs/online/hd0
./autorun.sh
👉 For controllers with firmware version v2.12.x the part '/gins/fs/' in the directory name must be replaced with '/home/user1/fs/'.
Plugin registration
-
During installation, the plugin will be registered
-
plugin registry file “/gins/fs/firmware/plugins/plugins.xml” will be created if it does not exist
-
an entry is added to the plugin registry file
-
-
The plugin registry file tells the Q.station firmware which plugins are installed and how they have to be started.
For example Plugin registry file after installation of the plugin “PluginExample_OnlineData”:
<Plugins>
<userland name="PluginExample_OnlineData">
<Exe>QStationPluginExample_OnlineData</Exe>
<Version>V1.01</Version>
<ArgStr/>
<License/>
</userland>
</Plugins>
👉 For Q.station with firmware version V2.12.x the part “/gins/fs/” in the directory name must be replaced with “/home/user1/fs/”.
Plugin start
Plugin mode: Activated
- The Q.station application executes the plugin to start with command line parameters read from the plugin registration file.
- The plugin starts its own XML-RPC Server and registers its XML-RPC interfaces (port for XML-RPC Server is provided by the firmware as command line parameter -serverport={port}).
- The plugin connects to the Q.station application XML-RPC interface.
- The Q.station application connects to the plugin XML-RPC interface {PluginName}/GInsPluginSystemAPI.
- The Q.station application executes the plugin Start function {PluginName}/GInsPluginSystemAPI/Start.
- The plugin loads its own configuration. If the configuration is OK, then the plugin starts with its desired activity.
- A live counter is incremented in the plugin activity loop and cyclically checked by the Q.station application.
- Q.station application provides the plugin state info via file #actual.sta.
Plugin mode: Debug
-
If debugging is required, the plugin mode is set to “debug” (PluginMode=2).
-
In this case, the plugin installation and registration take place with PluginMode = 1 with the exception that the plugin is not started automatically.
-
The plugin has to start manually
cd /gins/fs/firmware/plugins/{PluginName}
./{ProjName} -clientport=1200 -name={PluginName} &-
{ProjName}: plugin executable
-
{PluginName}: name with which the plugin was registered
-
-clientport={Port}: port to which the plugin connects (usually 1200)
-
&: to run it in the background
-
-
For example: Start plugin “PluginExample_OnlineData”
cd /gins/fs/firmware/plugins/PluginExample_OnlineData
./QStationPluginExample_OnlineData -clientport=1200 -name=PluginExample_OnlineData &👉 For Q.station with firmware version V2.12.x the part “/gins/fs/” in the directory name must be replaced with “/home/user1/fs/”.
Plugin status
-
Run-time information about every plugin is provided
-
Run states
-
Error states
-
Live counter “CycleCount” (to bind plugin activity to the Q.station Watchdog/Live signal handling)
-
Version
-
-
Run-time information provided via FTP
-
Reading file #actual.sta using FTP
- For example: Run-time information for plugin “PluginExample_OnlineData”
...
PLUGIN STATES:
Plugin 0: PluginExample_OnlineData Act: 1 Cycles: 6258 Version: V1.01 Port: 1201
...
-
-
Run-time information is provided via the plugin XML-RPC interface
-
Method /{PluginName}/GetStates using “GI.monitor”
-
Plugin control
-
the Q.station application on system state machine transitions or
-
individually via plugin XML-RPC interface /{PluginName}/GInsPluginSystemAPI/
Plugin XML-RPC interfaces
-
When a plugin is successfully registered and started, it connects to the Q.station application.
-
The plugin XML-RPC interface is automatically bound to the device XML-RPC interface creating an XML-RPC route {PluginName}/.
-
The plugin methods are accessible through the Q.station XML-RPC interface with a method call to /{PluginName}/{Subinterface}/{Method}. These calls are “routed” to the plugin XML-RPC interface.
-
Every plugin creates different subinterfaces:
-
/{PluginName}/system/
-
The internally used, built-in standard interface of every XML-RPC server.
-
-
/{PluginName}/GInsPluginSystemAPI/
-
Standard, built-in control interface for every plugin.
-
It is used by the Q.station application plugin handler to control the plugin.
-
This interface can also be used to control the plugin manually with the help of “GI.monitor”.
-
-
/{PluginName}/PluginAPI/
-
Plugin-specific interface created by the plugin developer.
-
This interface is usually defined in a model file PluginAPI.model.
-
This interface provides methods to read/write plugin configuration data, read internal plugin states, or even read online data generated by the plugin.
The limited performance of this text-based interface has to be considered when it is considered for data transfer! -
The name and methods, as well as the structs and types of parameters and results of this interface, are defined in the interface model file (“.model”) in the plugin project.
-
If the plugin should access the data interfaces (e.g. if the plugin produces values that should be written to outputs or data streams are read by the plugin and processed or redirected by the plugin) some configuration “objects” should be modeled in a standard way.
-
This gives the chance that the plugin configuration can be adjusted to match a certain Q.station system configuration within graphical user interfaces that do not have knowledge about the different plugins.
-
-
For example: XML-RPC subinterfaces for the plugin “PluginExample_OnlineData”:
<?xml version="1.0" encoding="utf-8"?>
<model>
<XmlRpcInterface Name="PluginAPI" ID="" Description="no" ApplicationName="OnlineExample" Revision="0.1">
<FileInclude Name="GInsXmlRpcStdAPI_Types.h" Global="true"/>
<Struct Name="TypeOutputVariable">
<Item Name="GIns_VariableName" Type="std::string"/>
<Item Name="Factor" Type="double"> Value="1"</Item>
<Item Name="Offset" Type="double"> Value="0"</Item>
</Struct>
<Struct Name="TypeConfig">
<Item Name="OutputVariables" Type="TypeOutputVariable[]"/>
<Item Name="GIns_SourceVariableName" Type="std::string"/>
</Struct>
<Method Name="Configure">
<Params>
<Item Name="Configuration" Type="TypeConfig"/>
<Item Name="SetDefault" Type="bool"/>
</Params>
<Results>
<Item Name="ReturnState" Type="GInsXmlRpcStdAPI::GIns_Info_State"/>
</Results>
</Method>
<Method Name="GIns_SelectOutputVariable">
<Results>
<Item Name="GIns_VariableName" Type="std::string[]"/>
<Item Name="ReturnState" Type="GInsXmlRpcStdAPI::GIns_Info_State"/>
</Results>
</Method>
<Method Name="GIns_SelectInputVariable">
<Results>
<Item Name="GIns_SourceVariableName" Type="std::string[]"/>
<Item Name="ReturnState" Type="GInsXmlRpcStdAPI::GIns_Info_State"/>
</Results>
</Method>
</XmlRpcInterface>
</model>
Plugin configuration
Plugins should use GInsXmlRpc compatible configuration:
-
source code is generated to handle configuration data (makes it very easy to develop plugin config handling)
-
functions are generated to access config via XML-RPC interface
-
the config can be read and written from other programs on the device or via a network connection
-
client source code for remote access to the config is generated and can be embedded in a PC configuration tool
-
standard tools like GI.monitor can inspect plugin functions and access config in a generic way
For example: Configuration for the plugin “PluginExample_OnlineData”:
- The plugin configuration file /gins/fs/firmware/plugins/{PluginName}/PluginConfiguration.xml is an XML file.
- 👉 For Q.station with firmware version V2.12.x the part “/gins/fs/” in the directory name must be replaced with “/home/user1/fs/”.
- The plugin configuration file contains an XML-RPC value.
<value>
<struct>
<id>struct</id>
<member>
<name>GIns_SourceVariableName</name>
<value>Variable 1</value>
</member>
<member>
<name>OutputVariables</name>
<value>
<array>
<data/>
</array>
</value>
</member>
</struct>
</value>