The Device Server Signal Interface

# 4. The Server Side

## 4.1 The Commands to Access Signals

Three commands must be defined in a device class to access signals. One to read an array of signal values, one to identify and to describe each signal value and one to update changed signal properties.

### 4.1.1 DevReadSigValues

The command reads an array of signal values. The array should contain all signals for this class. The data type for all signals of a class must be the same. Possible data types are long values, float values or double values. The command must always return an array, even if only one signal value is defined.

To avoid the polling of several commands in the data collector, the state of a device should be also treated as a signal and should be returned as the signal "DOMAIN/FAMILY/MEMBER/State" by this command.

Command list entry:

DevReadSigValues, read_signal_values, D_VOID_TYPE, D_VAR_FLOATARR, READ_ACCESS

Command function definition:

- long read_signal_vlaues (xxx ds, DevVoid *argin, DevVarFloat Array *argout, long *error)

- Description:

  Returns the signal values of a device.

- Arg(s) In:

  None

- Arg(s) Out:

  DevVarFloatArray signal_values - Array of signal values.

  long *error - Pointer to error code, in case routine fails.

### 4.1.2 DevGetSigConfig

The command reads the properties of all signals returned by DevReadSigValues. The order of the signals must be the same for the two commands. The first value returned by DevReadSigValues must correspond to the first set of properties returned by DevReadSigConfig.

The properties of all signals of a class are returned as a string array. The first string (element [0]) must indicate the number of properties per signal, to have the flexibility to add new properties. The number of elements in the string array will be:

> length = number of properties * number of signals + 1

The properties of the signals must be added to the string array by using the result of the method DevMethodReadProperties on the signal or multi signal object (see: the user guides of the two classes).

Command list entry:

DevReadSigConfig, read_signal_config, D_VOID_TYPE, D_VAR_STRINGARR, READ_ACCESS

Command function definition:

- long read_signal_config (xxx ds, DevVoid *argin, DevVarStringArray *argout, long *error)

- Description:

  Returns the signal properties of all signals of a device.

- Arg(s) In:

  None

- Arg(s) Out:

  DevVarStringArray signal_values - Array of signal properties.

  long *error - Pointer to error code, in case routine fails.

### 4.1.3 DevUpdateSigConfig

The command reinitialises all signal properties of all signals of a device. After an update of the resource database calling this command reinitialises all signal properties dynamically with their actual resource values. The goal is an interactive resource editor with a direct update of the device configuration.

The method DevMethodSignalsReset must be used on the signal or multi signal object (see: the user guides of the two classes)

Command list entry:

DevUpdatedSigConfig, update_signal_config, D_VOID_TYPE, D_VOID_TYPE, READ_ACCESS

Command function definition:

- long update_signal_config (xxx ds, DevVoid *argin, DevVoid *argout, long *error)

- Description:

  Reinitialises all signal properties of all signals of a device with the actual resource values.

- Arg(s) In:

  None

- Arg(s) Out:

  None

## 4.2 Coding Example using a Multi Signal Object

This example is for a device server written in "C". For the use in a "C++" device server the multi signal object must be created via the OIC interface, but can be used with the same functionality.

To use a multi signal object it must be created and initialised in the object_initialise() method:

            #include <MDSSignalP.h>
            #include <MDSSignal.h>

            /*
             * Create the signal objects specified for this class
             */
             if (ds__create (ds->devserver.name, mDSSignalClass,
                                   &ds->focus.msignal_obj, error) == DS_NOTOK)
                {
                return(DS_NOTOK);
                }
             if (ds__method_finder (ds->focus.msignal_obj, DevMethodInitialise)
                   (ds->focus.msignal_obj, focusClass->devserver_class.class_name,
                   error) == DS_NOTOK)
                {
                return(DS_NOTOK);
                }

Afterwards two commands can be implemented using the multi signal object:

    =====================================================
     Function:  	static long read_signal_config()
     Description:	Read the properties of all signals specified
     	for the focus power supply.
     Arg(s) In:	Focus ds       - pointer to object
     	void  *argin  - no input arguments
     Arg(s) Out:	DevVarStringArray  *argout - Array of signal properties
    	long *error   - pointer to error code, in case routine fails
    =====================================================
    static long read_signal_config (Focus ds, DevVoid *argin,
                                                       DevVarStringArray *argout, long *error)
    {
            *error = 0;
             if (ds__method_finder (ds->focus.msignal_obj,
                                               DevMethodReadProperties)
                    (ds->focus.msignal_obj, argout, error) == DS_NOTOK)
                   {
                    return(DS_NOTOK);
                   }
            return (DS_OK);
    }

    =====================================================
     Function: 	static long update_signal_config()
     Description:	Reinitialises all specified signal properties with
     	their actual resource values..
     Arg(s) In:	Focus ds       - pointer to object
     	void  *argin  - no input arguments
     Arg(s) Out:	void  *argout - no outgoing arguments
     	long *error     - pointer to error code, in case routine fails
    ====================================================
    static  long    update_signal_config (Focus ds, DevVoid *argin,
                                                          DevVoid *argout, long *error)
    {
             *error=0;
             if (ds__method_finder (ds->focus.msignal_obj,
                                                DevMethodSignalsReset)
                  (ds->focus.msignal_obj, error) == DS_NOTOK)
                 {
                  return(DS_NOTOK);
                 }
             return(DS_OK);
    }

The third command just has to return an array of values which must be ordered as the signal properties!

    ====================================================
     Function:	static long read_signal_values()
     Description:	Read the measurement and setpoint values
     	for this device.
    	[0] : current setpoint
     	[1] : voltage
      	[2] : current
     Arg(s) In:	Focus ds      - pointer to object
     	void  *argin  - no input arguments
     Arg(s) Out:	DevVarFloatArray  *argout - Array of signal values..
    	long *error   - pointer to error code, in case routine fails
    =====================================================
    static  long read_signal_values (Focus ds, DevVoid *argin,
                                                         DevVarFloatArray  *argout, long *error)
    {
            static float       values[3];
            *error = 0;
            .................
            -> Read the signal values here!
           .................
            argout->length     = 3;
            argout->sequence = &values[0];
            return (DS_OK);
    }

In the SRRF3 project the signal objects are also used to check the limits of incoming set-point values and to handle alarms on signals which change the state on a device.

4.1 - The Commands to Access Signals
4.1.1 - DevReadSigValues
4.1.2 - DevGetSigConfig
4.1.3 - DevUpdateSigConfig
4.2 - Coding Example using a Multi Signal Object

Generated with Harlequin WebMaker