RSC IDataLoggerService2
Available from 2020.6
Introduction
The DataLogger is a service component that transfers real-time data from the GDS to a database for recording and storage purposes. When starting and stopping the PLCnext Technology firmware, a configured DataLogger session is started and stopped automatically. The DataLogger then collects the task-synchronous values of the configured GDS ports with a given sampling rate and stores them with a time stamp into a database. To learn more about the DataLogger in general, read the DataLogger topic.
A DataLogger instance can be configured with a configuration file, or by means of PLCnext Engineer (firmware 2020.6 or higher), or with the RSC IDataLoggerService2
as described in this topic.
Note: DataLogger sessions initiated via this RSC service will not perform the Download Changes command in PLCnext Engineer!
This is true even if sessions are not currently running but are created already.
The blocking is indicated by an Arp.Services.DataLogger.Error
notification, containing the payload string: "Dynamic session detected! Download rejected!"
.
Unlike sessions that are started via this RSC service, sessions that are created via an XML configuration or in PLCnext Engineer are continued even after a Download All operation.
IDataLoggerService2
can be found in the API documentation.Using the RSC IDataLoggerService2
The IDataLoggerService2
can be used to manage DataLogger sessions and retrieve diagnostic or status information during firmware runtime.
You need the following header to use this service; include it via the #include
command:
Arp\Services\DataLogger\Services\IDataLoggerService2.hpp
Requesting a list of subscribed sessions
ListSessionNames()
Method
void IDataLoggerService2::ListSessionNames(ListSessionNamesResultDelegate resultDelegate)
The ListSessionNames
method can be used to request a list with the names of all created DataLogger sessions. Note: This method might list also sessions beginning with PCWE_
which are created by the PLCnext Engineer.
Adding a session dynamically
CreateSession()
Method
ErrorCode IDataLoggerService2::CreateSession(const RscString<512>& sessionName, bool persistent);
A new, empty session can be created using the CreateSession
method.
Note: A dynamically added session will be deleted automatically during the next Download All or when the controller is rebooted. As long as any dynamically added session exists, the Download Changes command in PLCnext Engineer will be rejected, even if the session is not running.
Parameters
The following parameters are required when creating a new session:
sessionName
: Name for the new session. The name must be unique. Must not begin withPCWE_
which is reserved by the PLCnext Engineer.persistent
:false
(default value): When the attribute is set tofalse
, the session will be deleted when the controller is disconnected.true
: When it is set totrue
, the session remains active until it is deleted.
Error codes
Code | Description |
ErrorCode::None |
Creating of the new session was successful. |
ErrorCode::AlreadyExists |
A session with the same name already exists. |
ErrorCode::OutOfMemory |
There is not enough memory space available to create a new session. |
ErrorCode::Unspecified |
A session could not be added. |
Removing a session dynamically
RemoveSession()
Method
ErrorCode IDataLoggerService2::RemoveSession(const RscString<512>& sessionName)
An existing session can be removed using the RemoveSession
method. A session can also be removed if it is in the SessionState::Running
state. The method requires the name of the session to be removed as parameter.
Parameters
sessionName
: Name of the session to be removed
Error codes
Code | Description |
ErrorCode::None |
The session was removed from the system. |
ErrorCode::NoSuchSession |
A session with the specified name does not exist. |
ErrorCode::Unspecified |
An error occurred when removing the session. |
Changing a session configuration
ConfigureSession()
, GetSessionConfiguration()
Methods
ErrorCode IDataLoggerService2::ConfigureSession(const RscString<512>& sessionname, const std::vector<SessionProperty>& properties)
ErrorCode IDataLoggerService2::GetSessionConfiguration(const RscString<512>& sessionname, std::vector<SessionProperty>& properties, boolean& isPersistent)
The ConfigureSession
method can be used to change the configuration of a session. Changes include the publishing rate and sampling rate as well as the buffer capacity. A list of attributes for configuring the DataLogger session can be found here.
Note: To change the configuration, a session must not be in SessionState::Running
.
The current configuration of a session can be requested using the GetSessionConfiguration
method that has the same parameters and error codes.
Parameters
The following parameters are required:
sessionName
: Name of the session to be configuredisPersistent
(only available withGetSessionConfiguration
): Returns if the session will remain (true
) when the connection to the server is closed or not. This configuration can be set with theCreateSession
method described above.properties
: List ofSessionProperty
elements that make up the session configurationSessionPropertyName
: In order to configure a session there are some special elements to set up. ASessionProperty
consists of a pair ofSessionPropertyName
and its value:SamplingInterval
The desired sampling rate. Can either be provided asInt64
which will be interpreted as microseconds count, or asstring
containing the actual unit, e.g. "100ms".TaskContext
(available from 2021.6 or newer)
The name of an ESM task which samples the values of all variables of this session, e.g.taskContext="myTaskName"
.
This attribute is optional. If it is configured thesamplingInterval
attribute will be ignored.PublishingInterval
The rate in which values are written to the session's sink. Can either be provided asInt64
which will be interpreted as microseconds count or asstring
containing the actual unit, e.g. "100ms".BufferCapacity
Amount of records buffered in the underlying ring buffer asUint16
(for more information on this, see DataLogger concept). E.g., an amount of10
for a session recording the variablesA
and B means that 10 data records containing the values ofTimestamp
, variableA
, variableB
,isConsistent
andRecordType
can be buffered before older records are overwritten.SinkType
:
The type of sink used by the session; possible values are:SinkType::Database
: Sink using an SQLite-based database to store the recordings permanently.SinkType::Volatile
: Sink used to store data in RAM within the application. If the controller is switched off or is restarted, the data will be lost.Access via file system is not possible with the volatile sink. Variables of this sink type can only be queried using Remote Service Calls (RSC) viaReadVariablesData
( see here for details).
SinkProperties
:
The sink properties are given as astring
in which several properties are separated by semicolon. Note: The maximum capacity of thestring
for setting sink properties is limited to 512 bytes. If the complete string exceeds this limit, the properties have to be split in two or more separate strings and passed as elements of theproperties
array toConfigureSession
.
Each property starts with a property keyword followed by an equal sign and the according setting. The property keywords correspond to the XML attributes of the<DataSink>
element in the file-based configuration. The following property keywords can be specified:Keyword SinkType Description rollover
SinkType::Database
Specifies if file rolling is activated.
true
= file-rolling is active. If not specified, the default isfalse
.writeInterval
SinkType::Database
Specifies amount of records until data is flushed. If not specified, the default value is
1000
.maxFileSize
SinkType::Database
,SinkType::Volatile
Specifies maximal capacity of a single file, or the maximal capacity of the volatile sink in bytes. The default value is
5000000
(~5MB).
Note: The maximum permissible value formaxFileSize
for volatile sinks is set to 150,000,000 bytes (~150 MB). If you specify a larger value, an error message and notification is generated but the session configuration will be kept anyway.maxFiles
SinkType::Database
Specifies the maximal amount of files until rolled files are deleted. Default is
-1
which means unlimited.dst
SinkType::Database
File path and name under which the data sink is to be stored.
Note: The DataLogger does not create folders. If you want to store a data sink under a specific path, you have to create it first.
storeChangesOnly
SinkType::Database
,SinkType::Volatile
Specifies if only changes are stored (
true
) or every value (false
).
If not specified, the default value isfalse
.deleteRatio
SinkType::Database
,SinkType::Volatile
Specifies amount of data in % which will be deleted if
maxFileSize
is reached. Oldest data will be deleted first.tsfmt
SinkType::Database
Specifies the format of the timestamp. Allowed values are
Raw
for auint64
format value, orIso8601
.
Examples
Database sink configuration:
SessionPropertyName |
Value |
SinkType |
SinkType::Database |
SinkProperties |
"writeInterval=1000;dst=/opt/plcnext/test.db;rollover=true;maxFiles=25" |
Volatile sink configuration:
SessionPropertyName |
Value |
SinkType |
SinkType::Volatile |
SinkProperties |
"storeChangesOnly=true;maxFileSize=5000000" |
Error codes
Code | Description |
ErrorCode::None |
The configuration was successfully changed. |
ErrorCode::NoSuchSession |
A session with the specified name does not exist. |
ErrorCode::NotSupported |
Changing the parameter after initial configuration is not supported. |
ErrorCode::InvalidConfig |
One of the assigned properties does not meet the component limits or the type of the property value is invalid. See log file for more information. |
ErrorCode::SessionRunning |
Session is not in SessionState::Stopped but is currently active( SessionState::Stopped is required to change the configuration). |
All values of a session are reconfigurable but the setting SinkType::Undefined
or SinkType::Empty
for the session property SinkType
will cause the service call to return ErrorCode::InvalidConfig
.
Adding and removing variables and ports
SetVariables()
Methods
void IDataLoggerService2::SetVariables(const RscString<512>& sessionName, SetVariablesVariableNamesDelegate variableNamesDelegate, SetVariablesResultDelegate resultDelegate)
New variables can be added or removed using the SetVariables
method. A maximum of 996 variables per session is allowed.
The session must not be in the SessionState::Running
when calling the method. If the session is in the SessionState::Running
state, the ErrorState::SessionRunning
error code is returned when calling the method.
The method SetVariables
first empties the list of recorded variables. Next the variables specified by the variableNamesDelegate
parameter are added to the list of recorded variables. If the old list differs from the current list, then the DataLogger will create a new table in the data base. The old table is retained. Take this into account in view of the maximum file size. When SetVariables
is called again with the original variable list, the previous table is continued.
To specify a new list of variables, you can also apply the SetVariables
method to a DataLogger session out of a file-based configuration. In the file-based DataLogger session, the Download Changes command is not rejected. However, the added variables are lost when applying Download Changes, and the variable list as configured in the XML file will be recorded unchanged further on.
Parameters
The following parameters are required:
sessionName
: Name of the session to which variables are to be added.variableNames
: Name of the variables to be added to the session.
Error codes
Code | Description |
ErrorCode::None |
Adding/removing the variables was successful. |
ErrorCode::SessionRunning |
Currently, the session is in the SessionState::Running state and can therefore not be reconfigured. |
ErrorCode::NoSuchSession |
A session with the specified name does not exist. |
ErrorCode::NotSupported |
The DataLogger does not support the data type of the variables. |
ErrorCode::NoSuchVariable |
The specified variable does not exist in the current project. |
ErrorCode::Unspecified |
The variable cannot be added or removed for some unknown reason. |
Starting/stopping the recording
StartSession()
, StopSession()
Methods
ErrorCode IDataLoggerService2::StartSession(const RscString<512>& sessionName)
ErrorCode IDataLoggerService2::StopSession(const RscString<512>& sessionName)
Recording of variables and ports during runtime can be started or stopped using the StartSession
or StopSession
method. If the session is in the state SessionState::Stopped
, and the PLCnext Engineer software performs a cold restart, warm restart, or hot restart, the session is automatically restarted.
Parameters
The following parameter is required:
sessionName
: Name of the session to be started or stopped
Error codes
Code | Description |
ErrorCode::None |
The session has been started or stopped. |
ErrorCode::NoSuchSession |
A session with the specified name does not exist. |
ErrorCode::Unspecified |
The session could not be started or stopped. |
Requesting status information
GetSessionState()
Method
ErrorCode IDataLoggerService2::GetSessionState(const RscString<512>& sessionName, SessionState& state)
The GetSessionState
method can be used to obtain information on the status of a session. The method requires the name of the session of which the status is to be requested as parameter.
Parameters
The following parameters are required:
sessionName
: Name of the session whose status is to be queriedstate
: Container for the session state. If the session does not exist the returned value isSessionState::None
.
Requesting logged variables of a session
GetLoggedVariables()
Method
ErrorCode IDataLoggerService2::GetLoggedVariables(const RscString<512>& sessionName, GetLoggedVariablesInfosDelegate infosDelegate)
The GetLoggedVariables
method can be used to request a list of information on the currently logged variables of a session.
Parameters
The following parameters are required:
sessionName
: Name of the sessioninfos
: Iterator which can be used to list logged variables after successful call
Requesting historical data
ReadVariablesData()
Method
ErrorCode IDataLoggerService2::ReadVariablesData(const RscString<512>& sessionName, DateTime startTime, DateTime endTime, ReadVariablesDataVariableNamesDelegate variableNamesDelegate, ReadVariablesDataValuesDelegate valuesDelegate)
It is possible to request historical data of a variable for a defined period. To do so, enter a start and end timepoint manually or call the method with service->ReadVariablesData(„TestSession“, Arp::DateTime(0), Arp::DateTime(0),
and so on (Arp::DateTime(0)
is the Iso8601
format for 0001-01-01T00:00:00.000000
)
All the values recorded for this period will be transmitted.
Note: This method can only access data stored in RAM. In case of multiple database files (rollover=true
), older data which persists in already closed files cannot be accessed by an RSC service. The names of these files can be retrieved by GetRotatedFileNames
method.
The ReadVariablesData
method can be used to request the data of the specified variables together with the associated time stamps. The data record created in this way contains the values in a static order without any additional information. The data record begins with a time stamp followed by the value of the specified variable.
Parameters
The following parameters are required:
sessionName
: Name of the sessionstartTime
: Start time of the data to be readendTime
: End time of the data to be readvariableNames
: Names of the variables whose data is to be read.values
: enumerator that stores the read values.
Example
Variables a1 and a2 of task A as well as variable b1 of task B are to be read.
The following values are returned:
time stamp of task A, a1, a2, b1, consistent flag, record type
time stamp of task B, a1, a2, b1, consistent flag, record type
The consistent flag
indicates if there is a data inconsistency due to recording gaps caused by performance problems or memory overflow. Click here for more information on this flag.
Record type
specifies whether the recording is continuous (RecordType::Continuous = 1
) or trigger-based. The trigger-based recording differs whether the record was recorded before, after or when a trigger was fulfilled (RecordType::PreCycle
, RecordType::Trigger
, RecordType::PostCycle
).
The number of returned data sets depends on the start and end time. The following timepoint constellations can be applied:
Start timepoint | End timepoint | Description |
0 | 0 | All available data sets will be returned |
0 | x | All available data sets <= x will be returned |
x | 0 | All available data sets >= x will be returned |
x | x | Data set with index x will be returned |
x | y | All available data sets between x and y (including x and y) will be returned |
y | x | All available data sets between x and y (including x and y) will be returned in reversed order |
Further information on the database layout can be found here.
Requesting the session membership of a port
GetSessionNames()
Method
void IDataLoggerService2::GetSessionNames(const RscString<512>& variablename, GetSessionNamesResultDelegate resultDelegate)
The GetSessionNames
method can be used to request the names of all the sessions that monitor a specific variable. If more than one session monitors the variable, the result list is automatically sorted according to the sampling rate of the session. Note: This method might list also sessions beginning with PCWE_
which are created by the PLCnext Engineer.
Parameters
The following parameter is required:
variablename
: Name of the variable for which the associated sessions are to be listed
Providing file names
GetRotatedFileNames()
Method
ErrorCode IDataLoggerService2::GetRotatedFileNames(const RscString<512>& sessionname, GetRotatedFileNamesFilenamesDelegate filenamesDelegate)
The GetRotatedFileNames
method can be used to request a list with file names that were created by a session during recording of variable values. The method requires the name of the session as well as a Delegate
that informs the user about the file names. File names are only output for sessions in which one or more new files were created after the maximum permissible file size was reached. Only the already completed files are shown (suffix 0, 1, 2 in the file name). The name of the files that are currently being written by the session are not returned.
Parameters
The following parameters are required:
sessionName
: Name of the session from which the file names are to be requestedfilenames
: Iterator to list the names of all rotated files if the call is successful
Error codes
Code | Description |
ErrorCode::None |
The method was executed successfully. |
ErrorCode::NoSuchSession |
A session with the specified name does not exist. |
ErrorCode::NoData |
A data sink has not yet been configured. |
Adding a trigger condition to a session
SetTriggerCondition()
Method
ErrorCode IDataLoggerService2::SetTriggerCondition(const RscString<512>& sessionName, const RscString<512>& taskName, uint16 preCycleCount, uint16 postCycleCount, SetTriggerConditionTriggerConditionDelegate triggerConditionDelegate)
With a trigger you can link the data recording of a session to a defined condition. The data recording is started or stopped when the trigger condition is met. With the method SetTriggerCondition
you can add a trigger condition to a session.
Parameters
The following parameters are required:
sessionName
: Name of the session to which a trigger condition is to be added.taskName
: Name of the task in which the trigger condition is evaluated.preCycleCount
: Amount of datasets recorded before the condition was triggered.postCycleCount
: Amount of datasets recorded after the condition is triggered (0 = endless).triggerCondition
: List of trigger items. All items are evaluated in the order of their position inside the list.
Error codes
Code | Description |
ErrorCode::None |
Adding the trigger condition to the session was successful. |
ErrorCode::NoSuchVariable |
The specified variable does not exist. |
ErrorCode::NotSupported |
The specified variable type is not supported. |
ErrorCode::InvalidConfig |
An invalid operation was queried |
ErrorCode::OutOfMemory |
The memory to store the specified cycles could not be allocated |
ErrorCode::Error |
An unspecified error occurred. |
Example
In the following example, MySession
will only be recording data if the value of the MyProgramInstance.Myvariable
is true
.
In that case, the recording will contain the data of 10 cycles before and 20 cycles after the trigger condition was reached. The data will be evaluated in the ESM task MyTask
.
const Arp::String sessionname = "MySession";
const Arp::String taskname = "MyTask";
std::vector<TriggerRpnItem> rpn;
TriggerRpnItem item;
item.Type = RpnItemType::Variable;
item.Item = "Arp.Plc.Eclr/MyProgramInstance.MyVariable";
rpn.push_back(item);
item.Type = RpnItemType::Constant;
item.Item = RscVariant<512>(RscType::Bool);
item.Item = true;
rpn.push_back(item);
item.Type = RpnItemType::Operation;
item.Item = TriggerConditionOperation::Equals;
rpn.push_back(item);
using TriggerDelegate = IDataLoggerService2::SetTriggerConditionTriggerConditionDelegate;
TriggerDelegate delegate = TriggerDelegate::create([&](IRscWriteEnumerator<TriggerRpnItem>& enumerator)
{
enumerator.BeginWrite(rpn.size());
for (const auto& entry : rpn)
{
enumerator.WriteNext(entry);
}
enumerator.EndWrite();
});
ErrorCode error = this->dataLoggerService->SetTriggerCondition(sessionname, taskname, 10, 20, delegate);