subscribeValues Function

In order to be notified of any changes of value in properties, the subscribeValues method allows subscribing to one or multiple properties in a Desigo CC system and executing a method when the values change.

It is possible to specify a fixed list of objects to which subscribe to, but it is also possible to provide a filter and the subscription will be dynamically applied to all the objects that match the filter. When a property changes its value, the callback method provided as parameter will be invoked. The script runs until at least one subscription is active and keeps the script alive. When the script is stopped, all the subscriptions are removed.

Syntax

It is possible to subscribe to the change of value in properties of one system object. See the following syntax:

 

(one instruction)

subscribeValues(<objectReference>, <propertyNames>, <callback>, <initialValue>, <singleValues>);

 

(two instructions with variable)

var obj = new BrowserObject(<objectReference>);

var result = subscribeValues(obj, <propertyNames>, <callback>, <initialValue>, <singleValues>);

 

It is possible to subscribe to the change of value in properties of many system objects. See the following syntax:

(one instruction)

subscribeValues(<BrowserObjects array>, <propertyNames>,

<callback>, <initialValue>, <singleValues>);

 

(multiple instructions with variables)

var obj1 = new BrowserObject(<objectReference1>);

var obj2 = new BrowserObject(<objectReference2>);

...

var objN = new BrowserObject(<objectReferenceN>);

var result = subscribeValues([obj1, obj2, ..., objN], [<propertyNames>], <callback>, <initialValue>, <singleValues>);

 

It is also possible to create a dynamic subscription providing a filter by designation, object model, or alias. See the following syntax:

var result = subscribeValues(<filter>, <propertyNames>, <callback>, <initialValue>)

 

For example:

var filter = new Filter();

filter.designation= "System1.ApplicationView:ApplicationView.Logics.Scripts";

subscribeValues(filter, "Notes", callback);

Parameters Usage

Parameter

Type

Default

Use

Annotation

objectReference

 

 

objectReferences

String

BrowserObject

Point

String Array

BrowserObject Array

Point Array

-

Mandatory

CNS full path (reference to the system object location). For example:
- String of system objects references: [<objectReference>, <objectReference>]
- BrowserObjects instances: [new BrowserObject(<objectReference>), new BrowserObject(<objectReference>)]

filter

Filter

-

Mandatory

Filter for the dynamic subscription.

For further reference about this object, see Supported Filters below.

propertyNames

String

String Array

-

Mandatory

Names of the properties for the subscription, or constants with values.

For further reference about this parameter, see the notes below.

callback

Function

-

-

Reference to the method that will be executed when changes of value occur. The format is
function callback(object, values) {}.
For further reference about this object, see the callback Function section below.

initialValue

Boolean

True

Optional

If True, the callback method is called with the initial values of the concerned properties. In a filter object , the callback function is also executed when the subscription starts and when a new point that belongs to the filter is created.

If False, the callback method is called after the values change for the concerned properties.

singleValues

Boolean

False

Optional

If True, the callback method is called for any changed property (in addition to any fixed properties).

If False, the callback method is called for all the properties of the concerned system object.

Note that the <singleValues> parameter is not required when a filter object is provided. The value for this parameter is always True and it is not necessary to provide such value.

Supported Filters

  • filter.designation: system object path, from root to object. For example, Scripts designation is: "System1.ApplicationView:ApplicationView.Logics.Scripts".
    It is possible to specify the designation with a specific wildcard character (*), at the end of the designation. By specifying this filter, the subscription will be applied to all the child nodes of the specified object. For example, if the designation of Scripts node is specified, the subscription will be applied to all its child nodes.
    It is also possible to specify the designation of a node that does not exist, but in this case it is necessary to provide the full designation (System.View:path). The subscription will be accepted, and it will be applied to all the child nodes that belong to this node when it is created, without restarting the script.
    A filter by designation can be used in conjunction with the other conditions (alias and object model). For example:
    var filter = new Filter();
    filter.designation= "System1.ApplicationView:ApplicationView.Logics.Scripts";
    filter.alias = "alias";
    subscribeValues(filter, "Notes", callback);
    or
    var filter = new Filter();
    filter.designation= "System1.ApplicationView:ApplicationView.Logics.Scripts";
    filter.alias = "alias";
    filter.objectModel = "GMS_Script";
    subscribeValues(filter, "Notes", callback);
  • filter.objectModel: filter condition in dynamic subscriptions where the filter will be applied to a set of points that is not fixed, but that can change over time in case of creation/deletion of points. For example, consider executing a subscription with a filter object for ObjectModel="GMS_Virtual_Analog":
    - When the subscription is executed in the script, it will be applied to all the objects that have "GMS_Virtual_Analog" as object model.
    - While the subscription is running, if a new instance with object model="GMS_Virtual_Analog" is created, the subscription will start monitoring the properties of this instance. Therefore, if the subscribed property of such object changes value, the callback method will be invoked.
  • filter.alias: filter condition in dynamic subscriptions where the alias is a string that can be used to identify a single data point. It is set using the Object Configurator application and it is not possible to assign the same alias to more than one data point. A dynamic subscription with alias as filter condition will monitor the alias attribute of objects. If a matching alias is set for an object, such object will be included in the subscription. It is possible to specify the alias condition with wildcards, but case sensitive is always True (system limit).
    It is also possible to combine the alias filter and the objectModel filter. In this case, the subscription will be applied to all the data points that match both the filter conditions.

Additional Notes for the <propertyNames> object

  • When an individual property is concerned, it is possible to directly specify the name of the property as string. For example: "Present_Value".
  • When many properties are concerned, it is necessary to create an array containing the names of all the desired properties. For example, ["Value", "Priority"].
  • It is possible to specify properties with fixed values, such as constants that are notified in the callback along with the other concerned properties. For example:
    ["Value", "MyConstantValue=3"].
  • The system objects can be of different types (different object models), as long as the subscription is done on properties having the same name. For example, you can subscribe to a BACnet Analog Input and a BACnet Binary Input at the same time, as long as the <propertyNames> object contains properties defined in both the object models (for example, Present_Value is correct, while Polarity will result in a subscription failure, because it is defined only for BACnet Binary Input.)

Callback Function

The callback method is called when any concerned property of a system object changes.

Syntax

The callback function must be declared as follows:

function myCallback(<changedObject>, <changedPropertiesAndValues>) {

    //... Do callback stuff here ...

}

 

Where:

  • <changedObject> is the system object to which it is subscribed and whose properties changed. It is possible to access its attributes via the Attributes property of the system object. This object can be used afterwards in other operations taking an object as input such as, read, getCommandList, executePropertyCommand, and so on.
    It is possible to print the designation of this object in one of the following ways:
    • console("object = {0}", object);
    • console("object.ToString = {0}", object.ToString());
    • console("object.Designation = {0}", object.Designation);
  • <changedPropertiesAndValues> is a dictionary (key-value pairs) that contains the changed properties (as keys) and the new property values. In particular, the names of the properties notified are the keys and the new (or fixed) values are the dictionary values.
    Possible operations on <changedPropertiesAndValues> (let's call it "values") are the following:
    • The Count field allows counting the changed properties.
      //Get the count of the notified elements
      var count = ChangedPropertiesAndValues.Count;
    • Use the JavaScript dot notation or bracket notation to access the dictionary property name.
      //Get a specific property by name with dot notation
      var presentValueProperty = ChangedPropertiesAndValues.Present Value;

      //Get a specific property by name with bracket notation
      var presentValueProperty = ChangedPropertiesAndValues["Present_Value"];

      Once the property is accessed, it is possible to obtain its value using .Value.
    • Access the value of the property
      //Access the value of the property
      var value = presentValueProperty.Value;

When calling the subscribeValues method, the callback function can be specified as string, object (including the function itself), inline (anonymous), or variable (which must be defined before use). Consequently, assuming to have the object object1 to which to subscribe to monitor the Value1 property, after declaring the function "MyCallback”, the following calls of subscribeValues can be executed:

 

var result = subscribeValues(object1, "Value1", "myCallback");

...

function myCallback (object, values) {

    console("Callback called. Changed object: {0}", object);

}

 

var result = subscribeValues(object1, "Value1", myCallback);

...

function myCallback (object, values) {

    console("Callback called. Changed object: {0}", object);

}

 

Alternatively, a callback can be defined as inline function (anonymous) as follows:

var result = subscribeValues(object1, "Value1", (function (object, values) {console("Inline callback called. Changed object: {0}", object); }));

 

Another option is to define a variable containing the callback function. For example:

var myF = function (object, values) {

    console("myF callback called. Changed object = {0}", object);

}

...

var result = subscribeValues(object1, "Value1", myF);

 

When executing a script that includes a subscription and an instruction while(true) in the callback, for example:

var result =

subscribeValues("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight",

"Value", onOrganizationModeChanged);

 

function onOrganizationModeChanged(object, values)

{

    console("New value = {0}", values.Value.Value);

    while(true) {}

}

 

  • If the script timeout is not set (such as, Timeout = 00:00:00 hh:mm:ss), the script remains in Activity Status=Running until it is manually stopped; as soon as the first invocation of the callback arrives, no other value change is received, because the callback remains stuck during the execution of the instruction while(true).
  • If the script timeout is set, the script ends when the timeout expires (Last Execution Status is Timed out).

Result

  • If the subscribe operation is successful, the result object contains the result of the subscribeValues method.
  • If any errors occurred during the subscribe operation, the subscribeValues method returns the SubscribeValuesResult object with the error that indicates the reason why the operation failed.

Error Handling

Errors can occur in case:

  • <objectReference> is null or empty.
    • result.error: "The designation is empty"/"Object is null"
  • <propertyNames> is null, empty, or invalid (for example, they are not string values; or the property type is invalid; or the property names are duplicated; or have fixed values.
    • result.error: "Invalid property."
  • When subscribing to various properties of a system object but the system object does not have a property with the specified name.
    • result.error: "Property not found"
  • The object type is invalid; null; or an empty string is passed among the subscription objects.
    • result.error: "Invalid object"
  • The system object is invalid.
    • result.error: "Node not found (System1.MyObject)"
  • <callback>:
    • Is null or empty
      result.error: "Invalid callback"
    • Is undefined. One of the following may happen:
      - The script generates the exception "xyz is not defined" and ends with an error.
      - If the callback was specified as a string, the Script Manager cannot detect the missing callback before trying to execute it, result.error: "Subscription succeeded" while the script will continue running. Anyway, when a change of value comes in, the exception "Can only invoke functions" is traced because the callback with the given name is undefined.
    • Wrong access to callback data. If a property is not among the property/value pairs returned in values, the instruction values.MyProperty generates an exception and the script ends.
  • <filter>:
    • Invalid filter object (such as the filter condition is different from designation, object model, or alias). The script ends with the following error: Invalid filter for subscription: ##### filter is not supported (where #### is the name of the filter property that is not supported).
    • No filter condition is specified. The script execution ends with the following error: Invalid filter for subscription: no filter conditions are specified
  • The filter by designation contains wildcard char * but in a different position from what expected. The script execution ends with the following error:
    • Invalid filter for subscription: you can only specify * wildcard at the end of designation filter
  • The provided designation cannot be resolved, and it is not fully defined (it must define all fields: System.View:path). The script execution ends with the following error:
    • Invalid filter for subscription: the provided designation is invalid

Examples of Use

 

How to print the result of a subscribe call

An easy way to print the result of a subscribe call is to invoke the method ToString or toString on the result itself. For example:

 

console("{0}", result.ToString());

 

Or

 

console("{0}", result);

 

Or

 

console(result);

 

How to subscribe to the change of the Present_Value property of an Analog Value object, without receiving the initial value

var result = subscribeValues("System1.ManagementView:ManagementView.FieldNetworks.MyBACnetNet.Hardware.1600/1600Test_device.1600/0Local_IO.1600/1AV_1", ["Present Value"], "onPresentValueChanged", false);

console("{0}", result.toString());

...

function onPresentValueChanged(object, values) {

    var presentValueItem = values.Present_Value;

    console("Object: {0}; New value: {1}", object, presentValueItem.Value);

}

 

At the end of the subscription, the output in the Console expander is:

 

Subscription succeeded

 

When Present Value changes in the monitored object, the output in the Console expander is:

"Object: System1.ManagementView:ManagementView.FieldNetworks.MyBACnetNet.Hardware.1600/1600Test_device.1600/0Local_IO.1600/1AV_1; New value: 45"

 

Note that the subscription was made without executing the callback function on the Initial Value. Also note that the callback function was passed as string while the presence of the Present_Value key was not checked in the dictionary of the modified values.

 

How to subscribe to the change of the Value property of DayNight and OnOff organization modes, using the same callback

var obj = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight");

var result = subscribeValues(obj, ["Value"], onOrganizationModeChanged);

console("Subscription1: {0}", result.toString());

 

var obj2 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff");

var result2 = subscribeValues(obj2, ["Value"], onOrganizationModeChanged);

console("Subscription2: {0}", result2.toString());

...

function onOrganizationModeChanged(object, values) {

    var newValue = values.Value.Value;

    console("Object = {0}; Value: {1}", object, newValue);

}

 

At the end of the subscription, the output in the Console expander is:

 

Subscription1: Subscription succeeded

Subscription2: Subscription succeeded

"Object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight; Value: 0"

 

"Object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff; Value: 1"

 

When Value changes for the DayNight monitored object, the output in the Console expander is:

"Object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight; Value: 1"

 

When Value changes for the OnOff monitored object, the output in the Console expander is:

"Object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff; Value: 0"

 

Note that the subscription was made with the execution of the callback function on the Initial Value. Also note that the same callback function was used because both the objects have the property named Value. The presence of the Value key was not checked in the dictionary of the modified values. Then the values were obtained using the field .Value.

 

How to subscribe to the change of the Value property of two OPC Texts and one OPC Analog Input, using the same callback

Use a fixed property to distinguish the object types when the callback is invoked and write the newly notified value to an OPC Text or to an OPC Analog Output respectively.

 

var obj1 = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1");

var result1 = subscribeValues(obj1, ["Value", "PropertyType=Text"], onValueChanged, false);

console("Subscription1: {0}", result1.toString());

var obj2 = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text2");

var result2 = subscribeValues(obj2, ["Value", "PropertyType=Text"], onValueChanged, false);

console("Subscription2: {0}", result2.toString());

var obj3 = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3.AnalogInput1");

var result3 = subscribeValues(obj3, ["Value", "PropertyType=AnalogInput"], onValueChanged, false);

console("Subscription3: {0}", result3.toString());

...

function onValueChanged(object, values) {

    if (object == null || values == null) {

        console("Invalid notification");

        return;

    }

    var newValue = values["Value"].Value;

    var propType = values.PropertyType.Value;

    console("Object = {0}; Value: {1}; PropertyType = {2}", object, newValue, propType);

 

    if (propType == "Text") {

        //Write the new value to another OPC Text object

        var obj = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_2.Text3");

        var result = executePropertyCommand(obj, "Value", "Write", newValue);

        console("Text change => executePropertyCommand result: {0}", result.toString());

    } else if (propType == "AnalogInput") {

        //Write the new value to an OPC Analog Output object

        var obj = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3.AnalogOutput1");

        var result = executePropertyCommand(obj, "Value", "Write", newValue);

        console("AnalogInput change => executePropertyCommand result: {0}", result.toString());

    }

}

 

The result of the subscriptions in the Console expander is:

    Subscription1: Subscription succeeded

    Subscription2: Subscription succeeded

    Subscription3: Subscription succeeded

 

When the Value property of Text1 changes (obj1), the output in the Console expander is:

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1; Value: hello; PropertyType = Text Text change => executePropertyCommand result: Command succeeded"

 

When the Value property of Text2 changes (obj2), the output in the Console expander is:

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text2; Value: hello; PropertyType = Text Text change => executePropertyCommand result: Command succeeded"

 

When the Value property of AnalogInput1 changes (obj3), the output in the Console expander is:

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3AnalogInput1; Value: 16.88; PropertyType = AnalogInput AnalogInput change => executePropertyCommand result: Command succeeded"

 

Note that each subscription was made without executing the callback function on the Initial Value. Each subscription was made on two properties of the object passing constant values to the callback function. A check was made of the modified values of the dictionary data. To access the dictionary properties dot notation and bracket notation were used. The executePropertyCommand function was called to update the Value property of the objects Text3 and AnalogOutput1.

 

How to subscribe to the change of value of various properties of a BACnet Analog Input, without receiving the initial value and requesting for single values

var obj = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyBACnetNet.Hardware.1600/1600Test_device.1600/0Local_IO.1600/1AI_1");

var result = subscribeValues(obj, ["Present Value", "Out Of Service", "Low Limit", "High Limit", "MyConst = 5"], onAnalogInputChanged, false, true);

console("{0}", result);

...

function onAnalogInputChanged(object, values) {

    if (object == null || values == null || values.Count == 0) {

        console("Invalid notification");

        return;

    }

}

 

At the end of the subscription, the output in the Console expander is:

 

Subscription succeeded

 

At each change of value of one of the properties of the monitored object, the output in the Console expander is one of the following:

 

    High_Limit = 0

    MyConst = 5

or

    Low_Limit = 0

    MyConst = 5

or

    Out_Of_Service = False

    MyConst = 5

or

    Present_Value = 42.347

    MyConst = 5

 

Note that the subscription was made without the execution of the callback function on the Initial Value, but it was requested a notification about each change of value. Data was checked in the dictionary of the modified values. Also note that the bracket notation was used to access the dictionary property.

 

How to use an inline callback

var obj = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1");

var result = subscribeValues(obj, ["Value"], (function (object, values) { console("Inline callback called. Changed object: {0}", object); } ),true);

console("Subscription1: {0}", result);

 

At the end of the subscription, the output in the Console expander is:

Subscription succeeded

"Inline callback called. Changed object: System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1"

 

When Value changes for the monitored object, the output in the Console expander is:

"Inline callback called. Changed object: System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1"

 

Note that the subscription was made with the execution of the callback function on the Initial Value. Also note the anonymous inline callback function in brackets while dictionary data for the modified values was not checked.

 

How to define and use a variable containing the callback function

var myFunction = function (object, values) {

    console("Changed object = {0}", object);

}

...

var obj1 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight");

var result1 = subscribeValues(obj1, ["Value"], myFunction);

console("Subscription1: {0}", result1);

 

var obj2 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff");

var result2 = subscribeValues(obj2, ["Value"], myFunction);

console("Subscription2: {0}", result2);

 

At the end of the subscription, the output in the Console expander is:

Subscription1: Subscription succeeded

Subscription2: Subscription succeeded

"Changed object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight"

 

"Changed object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff"

 

When Value changes for the monitored objects, the output in the Console expander is:

"Changed object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight"

 

Or

 

"Changed object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff"

 

Note that the subscription was made with the execution of the callback function on the Initial Value. Also note that the callback is passed as a variable (defined before its use).

 

How to subscribe to the change of value of the Value property of the organization modes DayNight, OccupancyStatus, OnOff, OpenClose, OperationalStatus

var obj1 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight");

var obj2 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OccupancyStatus");

var obj3 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff");

var obj4 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OpenClose");

var obj5 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OperationalStatus");

 

var result = subscribeValues([obj1, obj2, obj3, obj4, obj5], ["Value"], onOrganizationModeChanged);

...

function onOrganizationModeChanged(object, values) {

    var newValue = values.Value.Value;

    console("Object = {0}; Value: {1}", object, newValue);

}

 

The callback will be invoked once per object and the output in the Console expander is the initial value of each property:

 

Object =

System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight;

Value: 0

Object =

System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OccupancyStatus;

Value: 0

Object =

System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff;

Value: 0

Object =

System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OpenClose;

Value: 0

Object =

System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OperationalStatus;

Value: 0

 

Note that the subscription was made with the execution of the callback function on the Initial Value. Additionally, the callback function was passed as object. Since the <SingleValues> parameter was not specified (and the default is False), the callback is called once per object in the subscription even if only one of the monitored objects changes.

 

How to perform the same subscription as in the previous example, but using strings instead of objects

var result = subscribeValues(["System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight", "System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OccupancyStatus", "System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff", "System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OpenClose", "System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OperationalStatus, ["Value"],

onOrganizationModeChanged);

...

function onOrganizationModeChanged(object, values)

{

    var newValue = values.Value.Value;

    console("Object = {0}; Value: {1}", object, newValue);

 

The result is the same as in the previous example.

 

How to perform the same subscription as in the previous example, but using an array of mixed strings and objects

var obj1 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight");

var obj2 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OccupancyStatus");

var obj3 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OnOff");

var result = subscribeValues([obj1, obj2, obj3, "System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OpenClose", "System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.OperationalStatus"], ["Value"], onOrganizationModeChanged);

...

function onOrganizationModeChanged(object, values) {

    var newValue = values.Value.Value;

    console("Object = {0}; Value: {1}", object, newValue);

}

 

The result is the same as in the previous examples.

 

How to subscribe to heterogeneous objects that have the property "Value" (of different types)

//Organization Mode Value is a GmsEnum

var obj1 = new BrowserObject("System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight");

//OPC Text Value is a PvssString

var obj2 = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1");

//OPC Analog Input Value is a GmsReal

var obj3 = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3.AnalogInput1");

//OPC Binary Input Value is a GmsBool

var obj4 = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3.BinaryInput1");

var result = subscribeValues([obj1, obj2, obj3, obj4], ["Value"], onValueChanged, true, true);

console("Subscription: {0}", result);

...

function onValueChanged(object, values) {

    var newValue = values.Value.Value;

    console("Object = {0}; Value: {1}", object, newValue);

}

 

The output in the Console expander at the end of the subscription is:

 

Subscription: Subscription succeeded

"Object = System1.ManagementView:ManagementView.SystemSettings.OrganizationModes.DayNight; Value: 0"

 

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1; Value: helloworld"

 

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3.AnalogInput1; Value: 5576"

 

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_3.BinaryInput1; Value: False"

 

At any change of the Value property of one of the monitored objects, the output in the Console expander Is (in this example obj2):

 

"Object = System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1; Value: My New Text1"

 

Note that the subscription was made on different objects that have the Value property. The subscription was made with the execution of the callback function on the Initial Value. Additionally, the callback function was passed as object. Since the <SingleValues> parameter was specified, the callback is called only once for the object that changed its value among those monitored by the subscription.

 

How to subscribe to the change of value of an OPC Text

var obj = new BrowserObject("System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1");

var result = subscribeValues(obj, "Value", onValueChanged);

console("Subscription result: {0}", result.toString());

...

function onValueChanged(object, values) {

    if (object == null || values == null) {

        console("Invalid notification");

        return;

    }

 

    var objectValue = values["Value"].value.value;

    var objectQualityGood = values["Value"].value.qualityGood;

    var objectQuality = values["Value"].value.quality;

    var objectTimestampUTC = values["Value"].value.timestamp;

    if (objectQualityGood == false)

        console("Bad quality for {0}.", object);

    else

        console("Good quality for {0}. Value = {1}, Timestamp (UTC) = {2}", object, objectValue, objectTimestampUTC);

}

 

If this script is executed when the OPC DA driver is not running, the first notification indicates bad quality. Consequently, the output in the Console expander is similar to the following:

 

Subscription result: Subscription succeeded

Bad quality for

System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.

 

Once the OPC Server is started for simulation and the OPC DA driver, the output in the Console expander is similar to the following:

 

Good quality for

System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1.

Value = Today, Timestamp (UTC) = 5/5/2015 9:51:47 AM

Good quality for

System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1.

Value = --, Timestamp (UTC) = 5/5/2015 9:52:47 AM

Good quality for

System1.ManagementView:ManagementView.FieldNetworks.MyOPCNet.Server_Matrikon.Group_1.Text1.

Value = Your, Timestamp (UTC) = 5/5/2015 9:53:47 AM

 

How to subscribe with <initial value> = true and filter.designation

var filter = new Filter();

filter.designation= "System1.ApplicationView:ApplicationView.Logics.Scripts";

 

subscribeValues(filter, "Notes", callback, true);

 

function callback(object, values) {

    console("{0} has changed", object);

}

 

If the script is executed with only one instance named “MyScript1”, the output in the Console expander is: "MyScript1 has changed".

If a new instance is created, named "MyScript2", the output in the Console expander also includes: "MyScript2 has changed".

Every time the Notes property of MyScript1 or MyScript2 changes, the callback method will be executed, and a new message will display in the Console expander.

 

How to subscribe with <initial value> = False and filter.designation

var filter = new Filter();

filter.designation= "System1.ApplicationView:ApplicationView.Logics.Scripts";

 

subscribeValues(filter, "Notes", callback, false);

 

function callback(object, values) {

    console("{0} has changed", object);

}

 

If the script is executed with only one instance , named "MyScript1", since <initial value> is False, the Console expander does not display any information. As soon as MyScript1.Notes changes its value, the output is: "MyScript1 has changed".

If a new instance is created, named "MyScript2", again the Console expander does not display any information (<initial value> is False). As soon as MyScript2.Notes changes its value, the output also includes: "MyScript2 has changed".

Every time the Notes property of MyScript1 or MyScript2 changes, the callback method will be executed, and a new message will display in the Console expander.

 

How to subscribe with <initial value> = true and filter.objectModel

var filter = new Filter();

filter.objectModel = "GMS_Virtual_Analog";

subscribeValues(filter, "Value", callback, true);

...

function callback(object, values) {

    console("{0} has changed", object);

}

 

If the script is executed with only one instance with ObjectModel="GMS_Virtual_Analog", named "MyPoint1", the output in the Console expander is: "MyPoint1 has changed".

If a new instance of the same ObjectModel is created, named "MyPoint2", the output also includes: "MyPoint2 has changed".

Every time the Value property of MyPoint1 or MyPoint2 changes, the callback method will be executed, and a new message will display in the Console expander.

Note that the subscription is made by executing the callback function on the initial value and when the objects were created.

 

How to subscribe with <initial value> = False and filter.objectModel

var filter = new Filter();

filter.objectModel = "GMS_Virtual_Analog";

subscribeValues(filter, "Value", callback, false);

...

function callback(object, values) {

    console("{0} has changed", object);

}

 

If the script is executed with only one instance with ObjectModel="GMS_Virtual_Analog", named "MyPoint1", since <initial value> is False, the Console expander does not display any information. As soon as MyPoint1.Value changes its value, the output is: "MyPoint1 has changed".

If a new instance of the same object model is created, named "MyPoint2", again the Console expander does not show any information (<initial value> is False). As soon as MyPoint2.Value changes its value, the output in the Console expander is: "MyPoint2 has changed".

Note that the subscription is made by executing the callback function on the initial value and when the objects were created.

 

How to subscribe with <initial value> = true and filter.alias

var filter = new Filter();

filter.alias= "alias*";

 

subscribeValues(filter, "Value", callback, true);

...

function callback(object, values) {

    console("{0} has changed", object);

}

 

If the script is executed when there is only one instance with alias="alias1", named "MyPoint1", the output in the Console expander is: "MyPoint1 has changed".

If a new data point instance is created, named "MyPoint2", with alias = "alias2", the output in the Console expander is: "MyPoint2 has changed".

Every time the Value property of MyPoint1 or MyPoint2 changes, the callback method will be executed, and a new message will display in the Console expander.

 

How to subscribe with <initial value> = False and filter.alias

var filter = new Filter();

filter.alias= "alias*";

 

subscribeValues(filter, "Value", callback, false);

...

function callback(object, values) {

    console("{0} has changed", object);

}

 

If the script is executed when there is only one instance with alias="alias1", named "MyPoint1", since <initial value> is False, the Console expander does not display any information. As soon as MyPoint1.Value changes its value, the output is: "MyPoint1 has changed".

If a new instance of the same data point is created, named "MyPoint2", again the Console expander does not display any information (<initial value> is False). As soon as MyPoint2.Value changes its value, the output in the Console expander is: "MyPoint2 has changed".

Every time the Value property of MyPoint1 or MyPoint2 changes, the callback method will be executed, and a new message will display in the Console expander.

 

How to use a combined filter (alias and object model)

var filter = new Filter();

filter.alias = "alias*";

filter.objectModel = "GMS_Virtual_Analog";

subscribeValues(filter, "Value", callback);