# IRecorder Interface Definition

**URL:** <https://opendaq.discourse.group/t/irecorder-interface-definition/44>\
**Category:** ✋ Feature Requests\
**Created:** [December 13, 2024, 8:07am UTC](https://opendaq.discourse.group/t/irecorder-interface-definition/44 "2024-12-13T08:07:54Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dusan](https://yyz2.discourse-cdn.com/flex004/user_avatar/opendaq.discourse.group/dusan/32/17_2.png) [@Dusan](https://opendaq.discourse.group/u/Dusan)\
**Post date:** [December 13, 2024, 8:07am UTC](https://opendaq.discourse.group/t/irecorder-interface-definition/44/1 "2024-12-13T08:07:54Z")

</div>

**Introduction**

The IRecorder Interface shall inherit from the IFunctionBlock interface.  
The IRecorder Interface shall specify the start and stop methods.  
The IRecorder Interface shall at the minimum specify the start and stop methods.

Example code:

```auto
// case 1
struct IRecorder : public IFunctionBlock
struct IHBKRecorder : public IRecorder

class HBKRecorderImpl : public ImplementationOf<IHBKRecorder> {
  HBKRecorderImpl(ListPtr<> args)
}

// case 2 -> do not inherit
class HBKRecorderImpl : public ImplementationOf<IFunctionBlock, IRecorder, IHBKRecorder> {
  HBKRecorderImpl(ListPtr<> args)
}

FunctionBlockPtr fb = createWithImplementation<IFunctionBlock, HBKRecorderImpl>(args);

auto rec = fb.asPtr<IRecorder>();
auto hbkrec = fb.asPtr<IHBKRecorder>();

// actual implementation
struct IRecorder : public IFunctionBlock {
  virtual INTERFACE_FUNC ErrCode start() = 0;
}

template <typename T>
class GenericRecorderImpl<T> : public GenericFunctionBlockImpl<IRecorder, T> {
  ErrCode start() override;
}

class HBKRecorderImpl : public GenericRecorderImpl<IHBKRecorder> {
  HBKRecorderImpl(ListPtr<> args): public GenericRecorderImpl<IHBKRecorder>() {
  }
}

// You can get all recorders available on a device or openDAQ instance via: 
auto recorderListList = instance.getAvailableFunctionBlocks<IRecorder>();

auto recorderList = device.getAvailableFunctionBlocks<IRecorder>();

```

**openDAQ architectural concerns**

This section highlights some considerations about the `IRecorder::start/stop()` methods in regard to the current state of the SDK design.

When considering the currently available feature + those already being implemented (not counting the `IRecorder` interface), we already have 2 complementary ways of enabling/disabling recording:

##### setActive(true/false)

- Sets the `active` state of a component (function block) and all of its child components.
- Signals that are inactive don’t send data packets.
- Input ports that are inactive don’t receive data packets.
- As such, an inactive function block does not process data. By extension, an inactive recorder does not store data

##### setOperationMode()

- openDAQ currently defines three operation modes
  - Idle → Configuration, no data processing
  - Safe Operation → Configuration, full rate data, no physical sinks are online
  - Operation → Configuration, full rate, all sinks active; default state unless specified otherwise

- All states except for “Operation” are opt-in, meaning that a device is allowed to only support the “Operation” state.
- When considering the above states, a device that is not in “Operation” should not record data

Considering “Active” and “Operation Modes” together, we have:

- A way of enabling/disabling (stopping/starting) any function block, even when in “Operation” mode via `setActive`.
- A way of triggering storing based on a common device state shared across the entire device via `setOperationMode`

#### IRecorder::start/stop()

The question that remains is how `IRecorder::start()`and `IRecorder::stop()` can be slotted into the above behaviour without duplication that confuses end-users with multiple ways of achieving the same thing.

My (Jaka) proposal is to overload `start/stop` and have them be equivalent to `setActive(true)` and `setActive(false)`, while also being integrated with operation modes:

- `start` can only be called if the device is in “Operation” mode. When called, it sets `active`to `true`.
- Similarly, `stop` can only be called if the device is in “Operation” mode. When called, it sets `active` to `false`.

**Who shall implement the Feature**

openDAQ  
 Contribution

**Status**  
 Feature Planned on Roadmap  
 Feature Request is discussed in Working Group  
 Feature declined.
