Jump to: navigation, search

Difference between revisions of "HowTo:Implementing Live Values"


 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
== How Live Values work ==
+
Check out the [[Live_Values|Overview of Live Values]] before!
  
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 time stamp, 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).
+
== 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 meta class 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 meta class "cooling unit".  
+
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.
 
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 meta class ''OPC_SERVER'', and instances thereof can be used to configure a connection to a specific OPC server. Similarly, there is a meta class ''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.
+
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.  
+
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 ==
 
== 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.
  
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.<br>
 
<br>
 
 
# Navigate to the [[MetaClass]] ''OPC_SERVER'' via the ''[[Class Browser]]''.<br/> [[File:OPCServer.PNG|330 px|border]]
 
# Navigate to the [[MetaClass]] ''OPC_SERVER'' via the ''[[Class Browser]]''.<br/> [[File:OPCServer.PNG|330 px|border]]
 
# Add a new instance (OPC Server) to the [[MetaClass]] by using the [[Bulk Editor]].
 
# Add a new instance (OPC Server) to the [[MetaClass]] by using the [[Bulk Editor]].
Line 21: Line 21:
 
# Navigate to the [[MetaClass]] ''LIVEVALUE_METAPROPERTY'' via the ''[[Class Browser]]''.<br/> [[File:LMP.PNG|330 px|border]]
 
# Navigate to the [[MetaClass]] ''LIVEVALUE_METAPROPERTY'' via the ''[[Class Browser]]''.<br/> [[File:LMP.PNG|330 px|border]]
 
# Add a new instance (Live Value MetaProperty) to the [[MetaClass]] by using the [[Bulk Editor]].
 
# 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 bee shown.  
+
# 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. <br/> [[File:AddDatapoint.PNG|770 px|border]]
 
# Add the created Datapoint from step 4 to an instance of the above ''Metaclass'' to which it concerns. <br/> [[File:AddDatapoint.PNG|770 px|border]]
 
# Save the changes with {{key press|Ctrl|S}} or the save command.
 
# Save the changes with {{key press|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.
 +
 +
<source lang="csharp">
 +
using System;
 +
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");
 +
}
 +
}
 +
}
 +
 +
</source>
 +
 +
=== ILiveValueInformation ===
 +
The method TryGetLiveValue delivers LiveValueInformation objects:
 +
<source lang="csharp">
 +
namespace UBIK.Interface.LiveValues
 +
{
 +
    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; }
 +
    }
 +
}
 +
</source>
 +
 +
Information can be also extended using:
 +
<source lang="csharp">
 +
namespace UBIK.Interface.LiveValues
 +
{
 +
    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; }
 +
    }
 +
}
 +
</source>
 
== See also ==
 
== See also ==
 
* [[Plugins]]
 
* [[Plugins]]

Latest revision as of 10:24, 4 July 2024

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.

  1. Navigate to the MetaClass OPC_SERVER via the Class Browser.
    OPCServer.PNG
  2. Add a new instance (OPC Server) to the MetaClass by using the Bulk Editor.
  3. Navigate to the MetaClass OPC_DATAPOINT via the Class Browser.
    OPCDATAPOINT.PNG
  4. 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.
    OPCDatapointInstance.PNG
  5. Navigate to the MetaClass LIVEVALUE_METAPROPERTY via the Class Browser.
    LMP.PNG
  6. Add a new instance (Live Value MetaProperty) to the MetaClass by using the Bulk Editor.
  7. Add the newly created Live Value MetaProperty, from step 6, to the Metaclass where you want to have the live Values to be shown.
  8. Add the created Datapoint from step 4 to an instance of the above Metaclass to which it concerns.
    AddDatapoint.PNG
  9. 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;
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:

namespace UBIK.Interface.LiveValues
{
    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:

namespace UBIK.Interface.LiveValues
{
    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; }
    }
}

See also