dpConnectUserData()

Calls a callback function on data change of the defined data point values/attributes and passes them to it. In contrast to dpConnect(), this function allows you to also pass any data to the callback function.

Synopsis

int dpConnectUserData([class object,] string|function_ptr work, anytype userData[, bool answer = TRUE], string dpe1[, string dpe2 ...] | dyn_string dp_list);

Parameters

Parameter Meaning
object An object of a Control++ class.
work

Name of the callback function ("work function") that is called when data point values change.

Or

The name of a function pointer to the work function (callback function).

userData User-defined data which is passed as parameter to the callback function.
answer Specifies if the callback function should be executed the first time already when the dpConnectUserData() is called or first every time a value changes. The default value is TRUE (first callback is executed when the dpConnectUserData() is called).

dpe1, dpe2, ...

|

dp_list

Data point attributes or a data point list to be registered. If you pass a data point list, the DPEs and values in the work function are passed as a dyn_string dp-list and dyn_<type> Values.

CAUTION!

Do not use data points of different systems! The function dpConnectUserData() only works for one system. If dpConnectUserData() is used for at least two systems, it does not work and the following error message is shown:

 WCCOAui (1), 2006.09.26 14:11:19.266, PARAM,SEVERE, 175, this request cannot address more than one system, DP: dist_789:ExampleDP_Arg1.:_original.._value
WCCOAui (1), 2006.09.26 14:11:19.266, CTRL, WARNING, 76, Invalid argument in function,
VORSICHT: If a config that is queried via a connect function, is changed afterwards via the PARA module, the connect function will not work anymore. Re-select the config via the script editor.

Return Value

dpConnectUserData() returns 0, in the event of a failure returns -1.

Errors

Use the function getLastError() to retrieve errors. The function throwError() can be used to write an error message to the PVSS_II.log log file.

main()
{
  dyn_errClass err;
  int i;
  int pipeVal = 2;
  i = dpConnectUserData("add", pipeVal, "System1:ExampleDP_Arg1.", "System1:ExampleDP_Arg2.");
  err = getLastError();
  if(dynlen(err) > 0)
  {
    DebugN("An error occurred:", err);
    int errC = throwError(err); //write an error message to the PVSS_II.log log file
  }
  else
    DebugN("Function executed:", i);
}

add(int val, string dp1, float a, string dp2, float b)
{
  float res;
  dpSet("System1:ExampleDP_Result.", a + b + val);
  DebugN("dpGet:", dpGet("System1:ExampleDP_Result.",res ));
  DebugN("ExampleDP_Result:", res);
}

Description

Calls a callback function on data change of the defined data point values/attributes and passes them to it. In contrast to dpConnect(), this function allows to pass also any data to the callback function. This callback function (is also called work function) is executed spontaneous each time when some of the registered data point values /attributes (provided that all elements contained in the function call are passed) changes. An arbitrary number of DP attributes can be registered except some attributes of the "_alert_hdl" config. These attributes can be queried via the function alertConnect() (see the _alert_hdl table). Only the attributes "_prior", "_act_state_color", "_act_state_fore_color", "_act_state_font_style", "_text" and "panel" of the table are available for dpConnectUserData().

The DP attribute _status calls the callback function only then, when the status has changed. The behavior differs to the _value attribute, where the callback function is called for each value input (regardless of whether the value has changed or not).

When dpConnectUserData() is called the callback function is executed immediately once with the current data point values if the argument answer was not set to "false". If a specified attribute is modified while the callback function is executed, the next callback function call is executed first when the preceding call has been completed. The registration (function is called when values are changed) is valid until the function dpDisconnectUserData() stops the registration, the manager that executes is stopped or the panel is closed in the UI.

The registered callback function must contain the following parameters: in addition to the value (data type of the attribute) also the identifier of the data point attribute is returned as a string for each registered data point attribute. The order of these pairs (identifier + value) has to correspond to the registration via dpConnectUserData(). The name of the callback function can of course be assigned freely. Also the declaration within a library is possible. When the function names are same the local definition in a script wins against the global panel and manager definitions. Via this hierarchy it is possible to use the same function name more often in the same process image (panel) in the different event scripts of the graphics objects. The local function definition wins.

void workCB(anytype userData, dyn_string dps, dyn_anytype values);

or

void workCB(anytype userData, string dp1, <type> value1, string dp2, <type> value2, ...)

If the callback function of the dpConnectUserDatafunction contains default parameters, also the dpConnect call must contain these parameters. Otherwise the error message "WCCOAui (1), 2007.01.15 17:49:18.384, IMPL, WARNING, 54, Unexpected state, CtrlScript, dpVC, too less items in DpHLGroup, callback function myWork not started" is shown.

If the registered attributes are multilingual text elements these are returned to the control instance (Control manager, UI) only in the current language.

Use

The function dpConnect() is used above all for displaying or processing current values and states. If, for example, a value should be shown in a process image the registration for the value changes in a dpConnect() is made within the Initialize(). See also GEDI and Control scripts. The associated callback function is executed each time a value changes. The function updates the value representation in the process image.

If a callback function is not yet completed when an event occurs again the event is added to a queue until all previous function calls have been executed. If the frequency of the events is higher than as these can be processed, the queue of pending events and with it the memory consumption of the CTRL Manager or UI Manager keeps on growing. If a callback function has more events to process than the number set in the config file, the following warning (or another error output) is displayed in the Log Viewer:

"Function has ... pending runs-> DISCARDING"

The default maximum amount of the queue (events that have to be executed) is 200. As soon as this amount is reached the system discards all calls except the youngest and processes only the last value. The queue can grow again. The maximum value can be set selective via the config entry [general] ctrlMaxPendings in the UI and CTRL Manager sections.

If the config + attribute are left out when the data point elements are registered (see addressing) the system handles this as if the online value (_online.._value) would be specified.

Normally a dpConnect() with several registered elements returns a callback function call for each value change of an attribute. Thereby all "registered" values are passed to the CB function. If a number of value and attribute changes are sent in a single dpSet() the registration returns only a single common callback function call. A single callback function call is also returned for common registrations for attributes that belong together (like value, time stamp and status (quality) of a single data point element). See the last example.

Information about a drive should be shown in a device symbol. The data point type of the drive looks as follows:

Calculate C = A+B. The name of the callback function is add(). The parameters passed are 0 as user data, "Pipe_A.flow:_online.._value" and "Pipe_B.flow:_online.._value". The data point Pipe_C.flow is set via a dpSet() command.

main()
{
  int userData = 0;
  dpConnectUserData("add", userData, "Pipe_A.flow", "Pipe_B.flow");
}

void add(int userData, string dp1, float a, string dp2, float b)
{
  if ((a + b) > userData)
  {
    dpSet("Pipe_C.flow", a + b);
  }
  else
  {
    DebugN("Summe ist <= 0. Wert wurde auf Pipe_C.flow nicht geschrieben");
  }
}

In the last example the attribute identifiers _online.._value and _original.._value were left out (for example, "Pipe_B.flow:_online.._value"). If only the data point element is named the original value is automatically used for "set" operations and the online value for "read" operations.

A measured value that is displayed in the system via the data point element Drive014.speed should be visualized in a process image (panel). The value (display) should be formatted (decimal places) and the unit should be specified in a text field.

Solution

Add the following program to the Initialize script of the text field. The function dpValToString() formats the value according to the number format and engineer unit specified for the data point element. The option specified as comment would display the number without formatting and with an arbitrary number of decimal places in the text field.

main()
{
  float userData = 100;
  dpConnectUserData("displayValue", userData, "Drive014.speed");
}

void displayValue(float userData, string dpe, float speed)
{
  if (speed > userData)
  {
    this.text = dpValToString(dpe, speed, true); //this.text(speed)
  }
  else
  {
    this.text(userData);
  }
}

For more examples without passing user data, see dpConnect().

For general information on dpConnects, see dpConnect().

You can find an example of how to use a Control++ class instance in a connect function in the chapter dpConnect().

Assignment

Data point function, Waiting Control function

Availability

UI, CTRL