Check out the Overview of Live Values before!
How Live Values Work
Live values are special properties without a value that is persisted in the database. Instead, they get their current value frequently from a live value server, including a measurement quality indicator and a read timestamp, among other details. Live values can be used to display trends and current values (e.g., sensor values) from dynamic sources like process control systems (e.g., via OPC-UA).
In UBIK®, live value properties are defined by a special kind of MetaProperty, a live value meta property. So, if you want to add a live value to a UBIK® object, you first need to add such a meta property to the metaclass of the object in question. You can get such a live value meta property from creating an instance of the MetaClass LIVEVALUE_METAPROPERTY. This way, for example, you could define a property "temperature" on a metaclass "cooling unit".
So, following this example, how do individual "cooling unit" instances know their specific "temperature" values? An individual live value property holds the answer: It actually has a persisted value - a reference to a so-called live value data point. Such a data point knows a live value server (providing access to a process control system for example), and an identifier of (or path to) a dynamic variable, e.g. representing a specific temperature sensor in the process control system. This means, for a specific "cooling unit" instance, we want to configure the correct live value data point as a value of the "temperature" live value property.
Hence, we require a live value data point and a live value server. There is a UBIK® plugin UBIK.Interface.Module.OPCUA which we can use for getting those. That module implements a specific kind of live value server, namely the OPC-UA live value server. It is represented by a metaclass OPC_SERVER, and instances thereof can be used to configure a connection to a specific OPC server. Similarly, there is a metaclass OPC_DATAPOINT representing variable configurations. We want to have a data point instance with a link to a server instance (and a path to the variable we need). This data point instance must be set on the "temperature" property in our example.
With the UBIK.Interface.Module.OPCUA plugin, UBIK® will detect that there is a live value server and it will host a live value data service, supplying our "cooling unit" objects with their current "temperature" values.
Implementing Live Values in UBIK® Studio
First of all, download the UBIK.Interface.Module.OPCUA from the Augmensys Realease Portal/Plugins and copy them into the injections folder from your UBIK® Studio as well as in the injection folder of the Web Service.
- Navigate to the MetaClass OPC_SERVER via the Class Browser.
- Add a new instance (OPC Server) to the MetaClass by using the Bulk Editor.
- Navigate to the MetaClass OPC_DATAPOINT via the Class Browser.
- Add a new instance (OPC Datapoint) to the MetaClass by using the Bulk Editor. Configure the correct path to the OPC variable represented by this datapoint. As REF_OPC_SERVER take the server created before in step 2.
- Navigate to the MetaClass LIVEVALUE_METAPROPERTY via the Class Browser.
- Add a new instance (Live Value MetaProperty) to the MetaClass by using the Bulk Editor.
- Add the newly created Live Value MetaProperty, from step 6, to the Metaclass where you want to have the live Values to be shown.
- Add the created Datapoint from step 4 to an instance of the above Metaclass to which it concerns.
- Save the changes with Ctrl+S or the save command.
Accessing Live Values in UBIK® Studio
Example how a LiveValue can be accessed within WhoBert for debugging purposes for example. Can also be adapted to be used within the database code customizing.
The first part of the code ensures that live value servers are initialized and running before attempting to retrieve live values. Afterwards Live Value Information can be used as it retrieves and logs information about live values, such as their value, read timestamp, and age.
using System.Windows.Forms;
using UBIK.Kernel;
using UBIK.Runtime;
using UBIK.Runtime.Sys;
using UBIK.Compiler;
using System.Linq;
using UBIK.Interface;
using UBIK.Injection;
using System.Collections.Generic;
namespace Studio
{
public class ObjectTest
{
public void TestObject (params BaseClass[] InVariables)
{
Debugger.Output(this, "*** Started");
foreach (BaseClass obj in InVariables)
{
List<IUBIKLiveValueServer> servers = obj.Environment.GetInjectionManager().Plugins<IUBIKLiveValueServer>(TargetApplication.UBIK_WebService);
foreach (IUBIKLiveValueServer server in servers)
{
if (!server.GetStatus().Running)
{
server.InitLiveValueServer(obj.Environment);
server.Startup();
}
UBIK.Interface.LiveValues.ILiveValueInformation value;
//UID from the LiveValue Datapoint
if (server.TryGetLiveValue(new Guid("UID"), out value))
{
if (value.Value != null)
Debugger.Output(this, value.Value.ToString());
if (value.ReadTimeStamp != null)
Debugger.Output(this, value.ReadTimeStamp.ToString());
if (value.Age != null)
Debugger.Output(this, value.Age.ToString());
}
Debugger.Output(this, server.GetStatus().ToString());
}
}
Debugger.Output(this, "*** Finished");
}
}
}
ILiveValueInformation
The method TryGetLiveValue delivers LiveValueInformation objects:
{
public interface ILiveValueInformation
{
/// <summary>
/// Gets the value.
/// </summary>
/// <value>
/// The value.
/// </value>
object Value { get; }
/// <summary>
/// Gets the quality.
/// </summary>
/// <value>
/// The quality.
/// </value>
QualityTypes Quality { get; }
/// <summary>
/// Gets the quality description.
/// </summary>
/// <value>
/// The quality description.
/// </value>
string QualityDescription { get; }
/// <summary>
/// Gets the read time stamp.
/// </summary>
/// <value>
/// The read time stamp.
/// </value>
DateTime? ReadTimeStamp { get; }
/// <summary>
/// Gets the age.
/// </summary>
/// <value>
/// The age.
/// </value>
int? Age { get; }
}
}
Information can be also extended using:
{
public interface ILiveValueInformationV264 : ILiveValueInformation
{
/// <summary>
/// Attributes provides a possibility to add (any) information to a live value.
/// This gives us the possibility to hand over any back end server specific information to the client.
/// </summary>
/// <value>
/// The attributes.
/// </value>
UBIK.Service.DTO.V264.LiveValueAttribute[] Attributes { get; }
}
}