Connect to a Device

openDAQ™ provides Device connectivity features through Modules. Said Modules contain mechanisms for discovering and connecting to Devices. By listing available Devices, Modules are asked to return meta-information about Devices they can connect to. This metadata contains an address (connection string) at which the Device is accessible. The procedure of querying Modules for available Devices, as well as selecting the appropriate Module when connecting to a Device is done automatically by the openDAQ™ Instance and its default Root Device.

Related articles:

Discovering Devices

openDAQ™ provides three client and three server modules. They make possible to connect to openDAQ™ devices, as well as transfer their signal data. To discover available devices, we can use the getAvailableDevices method of the openDAQ™ instance which returns the list of devices info of all available devices. Device info contains information about device such as name, serial number, connection string, server capabilities, etc. Connection string is used to connect to the device. Prefix of connection string indentifies the protocol used to connect to the device or a type of device.

  • daqref:// indentifies the reference Device Module that simulates sine wave signals;

  • daq.opcua:// is a prefix of OPC UA device;

  • daq.ns:// indentifies the devices which supports native streaming protocol;

  • daq.lt:// is a prefix of device that supports streaming Lt protocol;

  • daq:// is a prefix of the device that supports multiple protocols and alows to connect with optimal protocol. The host will represent the device manufacturer and serial number and will have a list of server capabilities which represent the protocols that device supports and connection strings for each protocol.

Connecting to Devices

To connect to device developer can use either connection string from the device Info or if there is a need to connect with required protocol, use conenction string from server capability. Some server capabilities may contain multiple connection strings for the same protocol. The primary connection string can be view with the method getConnectionString and all possible addresses with the method getConnectionStrings.

Device info may contatin server capability only for OpcUa, Native and streaming Lt protocol. Devices like reference device and audio does not have server capabilities.

Connecting to openDAQ™ OPC UA devices

openDAQ™ provides three client and three server Modules. They enable us to connect to openDAQ™ Devices, as well as transfer their signal data. The openDAQ™ opcua_client_module uses an OPC UA client to connect to openDAQ™ OPC UA-compatible devices that are running a compatible OPC UA server. Discovered devices which supports OPC UA protocol has server capabilities with protocol name OpenDAQOPCUA in device info.

  • Cpp

  • Python

  • C#

#include <opendaq/opendaq.h>
#include <iostream>

using namespace daq;

int main(int /*argc*/, const char* /*argv*/[])
{
    // Create an openDAQ(TM) Instance
    InstancePtr instance = Instance();

    // Discover and print the names and connection strings of openDAQ(TM) OPC UA Devices
    ListPtr<IDeviceInfo> availableDevicesInfo = instance.getAvailableDevices();
    for (const auto& deviceInfo : availableDevicesInfo)
    {
        for (const auto& capability : deviceInfo.getServerCapabilities())
        {
            if (capability.getProtocolName() == "OpenDAQOPCUA")
            {
                std::cout << "Name: " << deviceInfo.getName() << ", Address: " << capability.getConnectionString() << std::endl;
            }
        }
    }

    return 0;
}
import opendaq

# Create an openDAQ(TM) Instance
instance = opendaq.Instance()

# Discover and print the names and connection strings of openDAQ(TM) OPC UA Devices
for device_info in instance.available_devices:
    for capability in device_info.server_capabilities:
        if capability.protocol_name == 'OpenDAQOPCUA':
            print('Name:', device_info.name, 'Address:', capability.connection_string)
using Daq.Core.Types;
using Daq.Core.OpenDAQ;

// Create an openDAQ(TM) Instance
Instance instance = OpenDAQFactory.Instance();

// Discover and print the names and connection strings of openDAQ(TM) OPC UA Devices
IListObject<DeviceInfo> availableDevicesInfo = instance.AvailableDevices;
foreach (var deviceInfo in availableDevicesInfo)
    foreach (var capability in deviceInfo.ServerCapabilities)
        if (capability.ProtocolName == "OpenDAQOPCUA")
            Console.WriteLine($"Name: {deviceInfo.Name}, Address: {capability.ConnectionString}");

The connection string of discovered Devices can be used to connect to them. Doing so adds the remote Device as a child of the Root Device. The Device can now be viewed, configured, and its data can be streamed. For configuration and inspection of its properties, OPC UA is used. Native Streaming protocol is used to stream the Device’s data.

  • Cpp

  • Python

  • C#

#include <opendaq/opendaq.h>
#include <iostream>

using namespace daq;

int main(int /*argc*/, const char* /*argv*/[])
{
    // Create an openDAQ(TM) Instance
    InstancePtr instance = Instance();

    // Discover and connect to all openDAQ(TM) OPC UA Devices
    ListPtr<IDevice> devices = List<IDevice>();
    ListPtr<IDeviceInfo> availableDevicesInfo = instance.getAvailableDevices();
    for (const auto& deviceInfo : availableDevicesInfo)
    {
        for (const auto& capability : deviceInfo.getServerCapabilities())
        {
            if (capability.getProtocolName() == "OpenDAQOPCUA")
            {
                devices.pushBack(instance.addDevice(capability.getConnectionString()));
            }
        }
    }

    return 0;
}
import opendaq

# Create an openDAQ(TM) Instance
instance = opendaq.Instance()

# Discover and connect to all openDAQ(TM) OPC UA Devices
devices = []
for device_info in instance.available_devices:
    for capability in device_info.server_capabilities:
        if capability.protocol_name == 'OpenDAQOPCUA':
            devices.append(instance.add_device(capability.connection_string))
using Daq.Core.Types;
using Daq.Core.OpenDAQ;

// Create an openDAQ(TM) Instance
Instance instance = OpenDAQFactory.Instance();

// Discover and connect to all openDAQ(TM) OPC UA Devices
IListObject<Device> devices = CoreTypesFactory.CreateList<Device>();
IListObject<DeviceInfo> availableDevicesInfo = instance.AvailableDevices;
foreach (var deviceInfo in availableDevicesInfo)
    foreach (var capability in deviceInfo.ServerCapabilities)
        if (capability.ProtocolName == "OpenDAQOPCUA")
            devices.Add(instance.AddDevice(capability.ConnectionString));

Connecting to other Devices

The openDAQ™ opcua_client_module allows for connecting to specifically openDAQ™ OPC UA-enabled Devices. However, openDAQ™ Modules can be written to connect to different kinds of Devices (local or remote). For example, the openDAQ™ ws_stream_cl_module (Web-socket Streaming client Module) and the openDAQ™ native_stream_cl_module (Native Streaming client Module) allow for connecting to remote Devices without using of OPC UA protocol. Another example is the openDAQ™ reference Device Module, which allows for the creation of reference Devices that simulate sine wave signals.

Depending on the Modules loaded we can connect to different types of Devices. When a Device is integrated into openDAQ™, it is added/connected to in the same manner as a openDAQ™ OPC UA Device, but using its own discovery mechanism and connection string format. For example:

  • the openDAQ™ reference Device Module uses addresses prefixed with "daqref://" and does not have server capability;

  • the openDAQ™ native_stream_cl_module has server capability with name openDAQ Native Configuration and uses addresses prefixed with "daq.ns://";

  • the openDAQ™ ws_stream_cl_module uses addresses prefixed with "daq.lt://" and have server capability with name OpenDAQLTStreaming.

  • Cpp

  • Python

  • C#

#include <opendaq/opendaq.h>
#include <iostream>

using namespace daq;

int main(int /*argc*/, const char* /*argv*/[])
{
    // Create an openDAQ(TM) Instance
    InstancePtr instance = Instance();

    // Discover and add all openDAQ(TM) reference Devices
    ListPtr<IDevice> devices = List<IDevice>();
    for (const auto& deviceInfo : instance.getAvailableDevices())
    {
        if (deviceInfo.getConnectionString().toStdString().find("daqref://") != std::string::npos)
        {
            devices.pushBack(instance.addDevice(deviceInfo.getConnectionString()));
        }
    }

    return 0;
}
import opendaq

# Create an openDAQ(TM) Instance
instance = opendaq.Instance()

# Discover and add all openDAQ(TM) reference Devices
devices = [instance.add_device(d.connection_string)
           for d in instance.available_devices
           if d.connection_string.startswith('daqref://')]
using Daq.Core.Types;
using Daq.Core.OpenDAQ;

// Create an openDAQ(TM) Instance
Instance instance = OpenDAQFactory.Instance();

// Discover and connect to all openDAQ(TM) reference Devices
IListObject<Device> devices = CoreTypesFactory.CreateList<Device>();
foreach (var deviceInfo in instance.AvailableDevices)
    if (deviceInfo.ConnectionString.StartsWith("daqref://"))
        devices.Add(instance.AddDevice(deviceInfo.ConnectionString));