Instance Configuration

For brevity, in C++, we assume that all the code is in namespace daq or it has been imported via using namespace daq;. Similarly, in Python, import opendaq is assumed.

The Instance is the top-level openDAQ™ object, serving as a container for the openDAQ context and the base Module Manager.

Related articles:

Creating the default openDAQ™ Instance

Upon creation, it generates a Client Device as the default Root Device. The Client Device is capable of using the Module manager to add Function Blocks and connect to any Device supported by the loaded Modules. The Client is set as the Root Device when the Instance is created if the developer has not set their own Device.

Creating openDAQ™ Instance with Instance Builder

openDAQ™ offers an advanced method for configuring an Instance through the Instance Builder. With this, developers can customize the Logger, Scheduler, Module Manager, and Root Device by either defining custom modules or modifying default objects.

  • Cpp

  • Python

InstanceBuilderPtr instanceBuilder = InstanceBuilder();
InstancePtr instance = instanceBuilder.build();
instance_builder = opendaq.InstanceBuilder()
instance = instance_builder.build()

Configuring openDAQ™ Instance from external Providers

Instance Builder supports configuring from external Providers like JSON file, environment variables, or command line arguments. More information about how to use Providers see Configuration Provider guide.

Configure openDAQ™ Instance Logger

By default, the Instance Logger level is set to the info log level if the project was built in release mode or debug log level if built in debug mode. There are two ways to override this default level. The first method is to set the global default logger level.

  • Cpp

  • Python

InstanceBuilderPtr instanceBuilder = InstanceBuilder();
instanceBuilder.setGlobalLogLevel(LogLevel::Warn);
InstancePtr instance = instanceBuilder.build();
instance_builder = opendaq.InstanceBuilder()
instance_builder.global_log_level = opendaq.LogLevel.Warn
instance = instance_builder.build()

In addition to adjusting the logging level globally, developers can customize the logging level for individual components and sinks. In the example below, the developer configures two logger sinks: StdOutLoggerSink with the default log level and BasicFileLoggerSink with the error log level. Furthermore, custom log levels are specified for the Instance and Some Module components.

  • Cpp

  • Python

InstanceBuilderPtr instanceBuilder = InstanceBuilder()
    .addLoggerSink(StdOutLoggerSink())
    .setSinkLogLevel(BasicFileLoggerSink("logfile.log"),  LogLevel::Error)
    .setComponentLogLevel("Instance", LogLevel::Warn)
    .setComponentLogLevel("Some Module", LogLevel::Off);
InstancePtr instance = instanceBuilder.build();
instance_builder = opendaq.InstanceBuilder()
instance_builder.add_logger_sink(opendaq.StdOutLoggerSink())
instance_builder.set_sink_log_level(opendaq.BasicFileLoggerSink(opendaq.String("logfile.log")), opendaq.LogLevel.Error)
instance_builder.set_component_log_level("Instance", opendaq.LogLevel.Warn)
instance_builder.set_component_log_level("Some Module", opendaq.LogLevel.Off)
instance = instance_builder.build()

An advanced method for configuring the Instance Logger involves setting up the Logger object and applying the desired configurations using the Logger configuration method.

  • Cpp

ListPtr<ILoggerSink> sinks = List<ILoggerSink>(StdOutLoggerSink());
LoggerPtr logger = LoggerWithSinks(sinks, LogLevel::Warn);
InstanceBuilderPtr instanceBuilder = InstanceBuilder().setLogger(logger);
InstancePtr instance = instanceBuilder.build();

Alternatively, a developer can create their own implementation of the Logger, which implements the ILogger interface.

Configure openDAQ™ Instance Module Manager

By default, the Instance Module Manager uses the current path for loading modules. Developers using the Instance Builder have the flexibility to either set a custom module path or replace the default Module Manager with a custom implementation that implements the IModuleManager interface.

Overriding module path
  • Cpp

  • Python

InstanceBuilderPtr instanceBuilder = InstanceBuilder().setModulePath("/path/to/modules");
InstancePtr instance = instanceBuilder.build();
instance_builder = opendaq.InstanceBuilder()
instance_builder.module_path = "/path/to/modules"
instance = instance_builder.build()
Setting module manager
  • Cpp

  • Python

ModuleManagerPtr moduleManager = ModuleManager("/path/to/modules");
InstanceBuilderPtr instanceBuilder = InstanceBuilder().setModuleManager(moduleManager);
InstancePtr instance = instanceBuilder.build();
module_manager = opendaq.ModuleManager(opendaq.String("/path/to/modules"))
instance_builder = opendaq.InstanceBuilder()
instance_builder.module_manager = module_manager
instance = instance_builder.build()

Configure openDAQ™ Instance Scheduler

By default, the Instance creates a Scheduler with a number of workers equal to the maximum physical threads available. For developers who want to manually adjust this number, the Instance Builder provides a method.

  • Cpp

  • Python

InstanceBuilderPtr instanceBuilder = InstanceBuilder().setSchedulerWorkerNum(2);
InstancePtr instance = instanceBuilder.build();
instance_builder = opendaq.InstanceBuilder()
instance_builder.scheduler_worker_num = 2
instance = instance_builder.build()

Similarly, developers can implement their own version of the IScheduler interface and integrate it into the Instance Builder.

  • Cpp

  • Python

LoggerPtr logger = Logger();
SchedulerPtr scheduler = Scheduler(logger, 4);
InstanceBuilderPtr instanceBuilder = InstanceBuilder().setScheduler(scheduler);
InstancePtr instance = instanceBuilder.build();
logger = opendaq.Logger(opendaq.List(), opendaq.LogLevel.Warn)
scheduler = opendaq.Scheduler(logger, 4)
instance_builder = opendaq.InstanceBuilder()
instance_builder.scheduler = scheduler
instance = instance_builder.build()

Configure openDAQ™ Default Root Device

The Instance has the Client Device as the default Root Device. A developer can modify the default Device by setting the default Root Device info and local id in the Instance Builder.

  • Cpp

  • Python

DeviceInfoConfigPtr defaultRootDeviceInfo = DeviceInfo("daqref://device1");
defaultRootDeviceInfo.setSerialNumber("ABCD-0000-0000-0000");
InstanceBuilderPtr instanceBuilder = InstanceBuilder()
    .setDefaultRootDeviceInfo(defaultRootDeviceInfo)
    .setDefaultRootDeviceLocalId("defaultRootDeviceLocalId");
InstancePtr instance = instanceBuilder.build();
import opendaq

default_root_device_info = opendaq.DeviceInfoConfig(opendaq.String("daqref://device1"), opendaq.String(""))
default_root_device_info.serial_number = "ABCD-0000-0000-0000"
instance_builder = opendaq.InstanceBuilder()
instance_builder.default_root_device_info = default_root_device_info
instance_builder.default_root_device_local_id = "defaultRootDeviceLocalId"
instance = instance_builder.build()

Configure openDAQ™ Root Device

Developers can replace the default Root Device with a Device using the given connection string. When the Instance is created, a connection to the Device with the provided connection string will be established, and the Device will be placed at the root of the component tree structure.

  • Cpp

  • Python

InstanceBuilderPtr instanceBuilder = InstanceBuilder().setRootDevice("daqref://device0");
InstancePtr instance = instanceBuilder.build();
instance_builder = opendaq.InstanceBuilder()
instance_builder.root_device = "daqref://device0"
instance = instance_builder.build()