Represents the schema of the single analytics algorithm configuration (also known as the information model), which will be used by the ABB's Powertrain analytics microservice.
Learn more about the algorithms' calculation process here.
Each field below is pointing to a specific key, with the information about the purpose and possible values. Click on a given section to learn more.
Additional links:
Name under which given algorithm will be referenced within configuration. Same Name cannot be used for
multiple algorithms which are applicable for a given asset!
In most cases it can be equal to the Path field. There are places, where it's handy to alias same function
multiple times, with different inputs.
Actual analytics azure function name, which shall be executed by the given algorithm. It can be same as Name, but it
is not required.
Example:
{
"Name": "PowerModuleTemperature",
"Path": "power_module_temperature",
"remaining keys are omitted"
}
Defines how often given algorithm will be run.
In case of Scheduled frequency, see Schedule key description.
Associated section in the specification: link.
ONLY required when ExecutionFrequency=Scheduled; for other values of execution frequency, this key is omitted.
Defines the custom schedule under which given algorithm will be executed, using the cron expressions.
Example for weekly algorithm:
{
"Name": "PowerModuleTemperature",
"Path": "power_module_temperature",
"ExecutionFrequency": "Scheduled",
"Schedule": "0 0 * * 0",
"remaining keys are omitted"
}
Simple constant value passed as an algorithm input with a given data type.
Note that DataType specifies which of the Constant<DateType> keys is required.
For example, when DataType="Int", then ConstantInt key is required.
Example:
{
"InputType": "Constant",
"DataType": "Int",
"InputName": "actual algorithm function input name",
"ConstantInt": 40
}
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"Constant"
Actual datetype of the constant value. It specifies which of the Constant<DateType> keys is required.
For example, when DataType="String", then ConstantString key is required.
Required when DataType=String
Required when DataType=Double
Required when DataType=Int
Required when DataType=Bool
Required when DataType=StringArray
Property associated with the asset, identified as an AssetPropertyKey. The list of the allowed AssetPropertyKey
is asset-specific; it is defined in the type config file, section AssetProperties (type config files are also
present in this project in functions->configuration->type_config folder).
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"AssetProperty"
Unique identifier of the given asset property. It is directly associated with the AssetPropertyTypeKey filed from
type config file.
Example values: DriveType, ShortTypeCode, FrameSize, MotorClass
SmartSensor feature value, identified as an SensorFeatureKey. The list of the allowed SensorFeatureKey
is asset-specific;
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"SensorFeature"
Unique identifier of the given sensor feature value.
Example values: SensorMeasurementInterval, BatteryLevel
Returns timeseries signal (timeseries), referenced by the symbolic_name. The signal will be sliced based on
the algorithm DataInterval (see description for more details).
Note that for drives, the external sensor signals are referenced without any prefix - to request for
the temperature, SymbolicName=temperature shall be provided.
In some cases, the symbolic name might be omitted. In motor suggested thresholds algorithm, the timeseries input is configured with empty symbolic name to allow different symbolic name signals to be provided. This way, it's up to the algorithm logic to decide how different symbolic names should be handled.
Example input definition:
{
"InputType": "Timeseries",
"InputName": "main_status_word",
"SymbolicName": "main_status_word",
"DataInterval": "Default"
}
If timeseries signal is missing for a given drive, Optional flag will define the behavior of the Powertrain
orchestrator:
Optional=false (default) - signal is mandatory, and if missing, algorithm function will not be executedOptional=true - algorithm will be executed, but the missing timeseries input will be omitted in the payloadSee Optional description to see some practical use cases for both options.
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"Timeseries"
Selects the actual timeseries signal which will be feed to the algorithm.
Signal mapping and list of all available drive signals is located within abb.drives.{drivetype}.{typeid}.json
file, section variables (stored in the
information model
repo).
Provided symbolicName shall match symbolicName field defined in this file.
Example snipped from drive signal mapping file:
{
"skipped beginning sections",
"variables": {
"01_02": {
"description": "SPEED (rpm)",
"unit": "rpm",
"dataType": "number",
"symbolicName": "motor_speed",
"textKey": "ABB.CMD.Backend.KPI.Parameters.acs800_asxr_as7r.01_02"
},
"01_03": {
"description": "FREQUENCY (Hz)",
"unit": "Hz",
"dataType": "number",
"symbolicName": "frequency_hz",
"textKey": "ABB.CMD.Backend.KPI.Parameters.acs800.Frequency"
},
"skipped rest of the mapping and end sections"
}
}
Selects the actual sensor timeseries signal which will be feed to the algorithm. Signal mapping and list of all available sensor signals is located within abb.drives.sensor.json file, section variables.
In practice, for external sensor, following values are supported for symbolicName:
Not yet supported - more details are needed!
Specifies the actual time slice of the Timeseries/`AlgorithmOutput which will be provided as the algorithm
input
Most of the allowed values are self-explanatory. Duration is the only one that requires additional Duration
key - see the Duration key description.
When DataInterval=Default then ExecutionFrequency is defining the input time slice:
ExecutionFrequency=Hourly - this hourExecutionFrequency=Daily - this dayAll, CalendarMonth and LatestValue are used only by the CBM algorithms.
Specifies the custom duration for the Timeseries/AlgorithmOutput input time slice. It is required only when
DataInterval=Duration. It is expected to be provided as ISO 8601
duration string.
For example to request last 30 days of results/signal: Duration="P30D"
Specifies the source of the timeseries signal. It can be either from the asset itself (Own) or from the
external drive (DrivingObject, DrivingMotor).
It is used mostly for the algorithms which are executed for the generic machine assets, where the asset itself
might not have the signal, but the signal is available from the driving object (for example, motor).
Default value is Own, which means that the signal will be requested from the asset itself.
Input type used to pass a single value of the timeseries signal, referenced by the symbolic_name.
This represents the latest value of the timeseries signal at the time of the algorithm execution.
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"TimeseriesValue"
Specifies the source of the timeseries signal. It can be either from the asset itself (Own) or from the
external drive (DrivingObject, DrivingMotor).
It is used mostly for the algorithms which are executed for the generic machine assets, where the asset itself
might not have the signal, but the signal is available from the driving object (for example, motor).
Default value is Own, which means that the signal will be requested from the asset itself.
Allows passing the results of the other algorithm as an input to the next algorithm. This way, we can chain algorithms into sequences, where one algorithm output is an input for a different algorithm.
<u>It applies only to the outputs of type ObjectOutput</u>. Other output types can be referenced by using
Timeseries input type (for Timeseries output) and AssetProperty (for AssetProperty output).
DataInterval controls the number of the results which will be passed to the algorithm input.
Note that algorithms are referenced by Name, not Path key (actual azure function name).
SourceOutputName allows pointing to specific object output of the source algorithm. It is required only when the
algorithm has more than one object output.
Examples:
{
"InputType": "AlgorithmOutput",
"InputName": "consumed_lifetimes_hourly",
"SourceAlgorithm": "CapacitorLifetimeConsumptionHour",
"SourceProperty": "consumedLifetime",
"DataInterval": "Default"
}
{
"InputType": "AlgorithmOutput",
"InputName": "model",
"SourceAlgorithm": "MotorConditionIndexThresholdCrossingAccX",
"SourceOutputName": "model",
"SourceProperty": "Details",
"Optional": true
}
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"AlgorithmOutput"
Specifies the actual time slice of the Timeseries/`AlgorithmOutput which will be provided as the algorithm
input
Most of the allowed values are self-explanatory. Duration is the only one that requires additional Duration
key - see the Duration key description.
When DataInterval=Default then ExecutionFrequency is defining the input time slice:
ExecutionFrequency=Hourly - this hourExecutionFrequency=Daily - this dayAll, CalendarMonth and LatestValue are used only by the CBM algorithms.
Specifies the custom duration for the Timeseries/AlgorithmOutput input time slice. It is required only when
DataInterval=Duration. It is expected to be provided as ISO 8601
duration string.
For example to request last 30 days of results/signal: Duration="P30D"
Name of the algorithm which will be a source of the results. SourceAlgorithm shall also be defined for a given asset.
Selects the specific object from the algorithm output, when there is more than one algorithm returned.
For example, let the response from the algorithm function has two outputs:
{
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "model",
"Retention": "Latest"
},
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Retention": "Default",
}
]
}
SourceProperty allows to select key from the Data dictionary. For example, by setting SourceProperty="key_1",
"value 1" will be passed to the algorithm function input.
SourceProperty can be also nested, e.g. SourceProperty="key_2.nested_key_1" will pass "value 2" to the
algorithm function input.
Selects the provided key from the algorithm output dictionary.
For example, sample response from the algorithm function has the following form:
{
"Objects": [
{
"OutputName": "model",
"OutputType": "Object",
"Data": {
"version": 1,
"params": {
"maximumModelAge": "P100D",
"warningThreshold": 2.0,
"alarmThreshold": 3.0
}
}
},
{
"OutputName": "algorithm_output",
"OutputType": "Object",
"Data": {
"Index": 2,
"Timestamp": "2023-01-05T03:00:00",
"Value": 5.0,
"WarningThreshold": 2.0,
"AlarmThreshold": 3.0
}
}
]
}
SourceOutputName allows to select which output object we want to use as an input to another algorithm.
In case we want to use the model then we need to set SourceOutputName="model".
In case when the algorithm outputs only a single output object, then the OutputName in the output data and
the SourceOutputName in the input object, can be omitted. This is because they both have the same default value
equal to algorithm_output.
Specifies the desired format of the AlgorithmOutput input.
Results will be passed as a list of objects (dictionaries) without any additional transformation. If this is the
desired behavior, AlgorithmOutputInputDataType field shall not be specified.
Example:
{
"InputType": "AlgorithmOutput",
"InputName": "consumedLifetimesHourly",
"SourceAlgorithm": "IgbtThermalCycleHour",
"SourceProperty": "consumedLifetime",
"DataInterval": "day"
}
Will fetch the consumedLifetime key from each result within this day and form the following input:
[0.032, 0.022, 0.012, "remaining values skipped"]
Will attach the date to each result value, creating the input in the following form:
[{"date": "date in 'yyyy-MM-dd'", "value": "actual value"}, {"..."}]
For example:
[{"date": "2022-01-12", "value": 0.0304}, {"date": "2022-01-13", "value": 0.045}, {"..."}]
Used currently only by the CBM graph points algorithm.
Input type used to pass events data to the algorithm. It is expected that the events data will be provided in a specific format, typically as a list of event objects.
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"Events"
Input type used to pass a collection of files to the algorithm. This is typically used for algorithms that require file-based inputs, such as raw data files or periodic raw data files.
The file type can be specified using the FileType enum, and the DataInterval specifies the time slice
for which the files are relevant. The Duration field can be used to specify a custom duration for the input.
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"Files"
Represents the type of files that can be passed to the algorithm as input. This enum is used to specify the type of files, such as raw data files or periodic raw data files.
Specifies the actual time slice of the Timeseries/`AlgorithmOutput which will be provided as the algorithm
input
Most of the allowed values are self-explanatory. Duration is the only one that requires additional Duration
key - see the Duration key description.
When DataInterval=Default then ExecutionFrequency is defining the input time slice:
ExecutionFrequency=Hourly - this hourExecutionFrequency=Daily - this dayAll, CalendarMonth and LatestValue are used only by the CBM algorithms.
Specifies the custom duration for the Timeseries/AlgorithmOutput input time slice. It is required only when
DataInterval=Duration. It is expected to be provided as ISO 8601
duration string.
For example to request last 30 days of results/signal: Duration="P30D"
TODO: Validate after final implementation in the backend.
Input type used to pass a sequence of lubrication dates to the algorithm. This is typically used for algorithms that require lubrication data, like Regreasing Advice algorithm.
Associates input with actual algorithm function input. InputName can be provided using original snake case notation,
used in the algorithm request definition <u>or</u> the same name converted to PascalCase naming convention.
To avoid confusion, it is recommended to use the same naming convention as in the algorithm request definition.
For example, following input definition:
{
"InputName": "my_input_name",
"InputType": "actual input type",
"other fields are depending on the input type"
}
Will match the following algorithm request definition:
class MyAlgorithmRequest(AlgorithmRequestParser):
my_input_name: ActualInputType # <- this input will be matched by the input definition above
other_input: OtherInputType
Boolean flag which indicates if the input shall be optional. If set to false (default), and if given input is
missing, Powertrain will generate error at payload preparation stage (with the exception of Timeseries input type -
see below). This is, in most cases, the desired behaviour.
For Timeseries input type, if given input is mandatory (Optional=false), and requested signal cannot be found,
algorithm function will not be executed at all - error will not be generated. This behaviour is handy when
dealing with external sensor signals - we can detect external sensor presence by checking if given sensor
signal exists (unfortunately there is no direct algorithm condition for detecting sensor presence).
Example of external sensor detection using Optional flag:
{
"Name": "EnvironmentTemperature",
"Path": "environment_temperature",
"ExecutionFrequency": "Hourly",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "temperature",
"SymbolicName": "temperature",
{# Since there is no condition to detect external sensor existence, we will mark this timeseries as
mandatory. Powertrain backend will NOT run the algorithm if the mandatory timeseries input is not present;
no error will be raised too. #}
"Optional": false,
"DataInterval": "Default"
}
],
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default"
}
]
}
Optional=true case can be used for input selection. It means that we will request, in the configuration, two (or
more) timeseries inputs and on the request definition level we will select the signal which will be passed to the actual
algorithm function, based on the signal presence. If Optional=true input will be missing, algorithm function
will still be executed.
Example of input selection:
{
"Name": "SomeAlgorithm",
"Path": "some_algorithm",
"Inputs": [
{
"InputType": "Timeseries",
"InputName": "sensor_temperature",
"SymbolicName": "temperature",
"DataInterval": "Default",
"Optional": true
},
{
"InputType": "Timeseries",
"InputName": "internal_temperature",
"SymbolicName": "ctrl_board_temp",
"DataInterval": "Default"
}
],
"remaining keys are omitted"
}
And associated algorithm request definition:
class SomeAlgorithmRequest(AlgorithmRequestParser):
sensor_temperature: DriveTimeseries | None = None
internal_temperature: DriveTimeseries
@property
def temperature(self) -> DriveTimeseries:
return self.sensor_temperature or self.internal_temperature # <- input selection, with the priority on the
# sensor_temperature input
"LubricationDates"
Defines the list outputs of the algorithm. In the analytics microservice, each algorithm can have multiple outputs of different types - this behaviour is different than in the old CMD (one result per algorithm).
Technically, different types of outputs are stored by different microservice:
ObjectOutput is stored in the internal database of the analytics microserviceTimeseriesOutput is stored in the timeseries microserviceAssetPropertyOutput is stored in the asset microserviceIn practise, most of the algorithms will have only one output, usually of ObjectOutput type.
Currently not used by any of the algorithms - more details are needed!
Unique identifier of the output. If algorithm is outputting more than one result, those results needs to have separate
OutputName.
Note that OutputName can be used to reference the given result of the algorithm as the algorithm input, but it
only works for OutputType=ObjectResult - see AlgorithmOutputInput for the details.
For output with OutputType=Timeseries, SymbolicName is such a key; for AssetProperty output, AssetPropertyKey
shall be used for that purpose.
Optional field, that marks given algorithm as an algorithm to be displayed on the Powertrain portal.
AlgorithmUsage will point to the exact place where the given result will be used. Trends creates mapping
between the actual properties (keys) within the result dictionary, and the thing to be displayed in the
Powertrain portal graph.
Example:
{
"Name": "DriveStatus",
"Path": "drive_status",
"ExecutionFrequency": "Daily",
"Inputs": ...,
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default",
"Description": {
"AlgorithmUsage": "KpiThreshold",
"Trends": [
{
"PropertyName": "KPI",
"ConditionTrendKey": "Kpi"
}
]
}
}
]
}
Represents the section of the Powertrain portal, where the given result will be displayed.
Represents the type of the condition index.
Mapping between the actual key is the algorithm result dictionary (PropertyName) and TrendKey used in the
Powertrain portal graph.
Represents the value to be displayed in the Powertrain portal graph(s). Values are taken from the algorithm framework specification.
Boolean flag which indicates if the output might be optional. If set to false (default), then it is guaranteed that the output field will be present in the algorithm response. If true then the output field might not be present in the algorithm response.
There are some algorithms that returns some outputs only if certain conditions about the inputs are met. By allowing setting the optional flag to True for those outputs we are indicating that those outputs might not be present for some of the algorithm's responses.
"Timeseries"
Symbolic name, under which the algorithm result will be stored. Results can be then accessed as any other timeseries inputs, using given symbolic name.
Currently not used by any of the algorithms - more details are needed!
Unique identifier of the output. If algorithm is outputting more than one result, those results needs to have separate
OutputName.
Note that OutputName can be used to reference the given result of the algorithm as the algorithm input, but it
only works for OutputType=ObjectResult - see AlgorithmOutputInput for the details.
For output with OutputType=Timeseries, SymbolicName is such a key; for AssetProperty output, AssetPropertyKey
shall be used for that purpose.
Optional field, that marks given algorithm as an algorithm to be displayed on the Powertrain portal.
AlgorithmUsage will point to the exact place where the given result will be used. Trends creates mapping
between the actual properties (keys) within the result dictionary, and the thing to be displayed in the
Powertrain portal graph.
Example:
{
"Name": "DriveStatus",
"Path": "drive_status",
"ExecutionFrequency": "Daily",
"Inputs": ...,
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default",
"Description": {
"AlgorithmUsage": "KpiThreshold",
"Trends": [
{
"PropertyName": "KPI",
"ConditionTrendKey": "Kpi"
}
]
}
}
]
}
Represents the section of the Powertrain portal, where the given result will be displayed.
Represents the type of the condition index.
Mapping between the actual key is the algorithm result dictionary (PropertyName) and TrendKey used in the
Powertrain portal graph.
Represents the value to be displayed in the Powertrain portal graph(s). Values are taken from the algorithm framework specification.
Boolean flag which indicates if the output might be optional. If set to false (default), then it is guaranteed that the output field will be present in the algorithm response. If true then the output field might not be present in the algorithm response.
There are some algorithms that returns some outputs only if certain conditions about the inputs are met. By allowing setting the optional flag to True for those outputs we are indicating that those outputs might not be present for some of the algorithm's responses.
"AssetProperty"
Most common output type - it can hold any result in the form of the dictionary. Other algorithms can then
reference this output as an input by using AlgorithmOutput input type.
Example:
{
"Name": "DriveStatus",
"Path": "drive_status",
"ExecutionFrequency": "Daily",
"skipped inputs",
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Retention": "Default"
}
]
}
If the algorithm returns more than one output object, then OutputName shall be used to reference the given result.
Output names have to be unique. Later, when the algorithm output is used as an input to another algorithm
function, OutputName value shall be used to reference the given result.
It can be achieved by using the SourceOutputName key in the AlgorithmOutputInput input type.
Unique identifier of the output. If algorithm is outputting more than one result, those results needs to have separate
OutputName.
Note that OutputName can be used to reference the given result of the algorithm as the algorithm input, but it
only works for OutputType=ObjectResult - see AlgorithmOutputInput for the details.
For output with OutputType=Timeseries, SymbolicName is such a key; for AssetProperty output, AssetPropertyKey
shall be used for that purpose.
Optional field, that marks given algorithm as an algorithm to be displayed on the Powertrain portal.
AlgorithmUsage will point to the exact place where the given result will be used. Trends creates mapping
between the actual properties (keys) within the result dictionary, and the thing to be displayed in the
Powertrain portal graph.
Example:
{
"Name": "DriveStatus",
"Path": "drive_status",
"ExecutionFrequency": "Daily",
"Inputs": ...,
"Outputs": [
{
"OutputType": "ObjectResult",
"OutputName": "algorithm_output",
"Optional": False,
"Retention": "Default",
"Description": {
"AlgorithmUsage": "KpiThreshold",
"Trends": [
{
"PropertyName": "KPI",
"ConditionTrendKey": "Kpi"
}
]
}
}
]
}
Represents the section of the Powertrain portal, where the given result will be displayed.
Represents the type of the condition index.
Mapping between the actual key is the algorithm result dictionary (PropertyName) and TrendKey used in the
Powertrain portal graph.
Represents the value to be displayed in the Powertrain portal graph(s). Values are taken from the algorithm framework specification.
Boolean flag which indicates if the output might be optional. If set to false (default), then it is guaranteed that the output field will be present in the algorithm response. If true then the output field might not be present in the algorithm response.
There are some algorithms that returns some outputs only if certain conditions about the inputs are met. By allowing setting the optional flag to True for those outputs we are indicating that those outputs might not be present for some of the algorithm's responses.
"ObjectResult"
Defines a storage period of the algorithm results of type ObjectOutput in the internal analytics service database.
In the vast majority of the cases, it shall be set to Default!
Unlimited, UnlimitedPerMonth and Latest are currently used only by the CBM algorithms.
Allows to specify conditions for algorithm execution. Algorithm will be executed only when all conditions are met.
Example for algorithm which will be executed only for water cooled drives:
{
"Name": "OnlyForWaterCooledDrives",
"Path": "some_azure_function",
"ExecutionFrequency": "Daily",
"inputs and outputs are omitted",
"Conditions": [
{
"PropertyName": "CoolingType",
"DataType": "String",
"ValueString": "Air"
}
]
}
Actual datetype of the condition property value. It specifies which of the Value<DateType> keys is required.
For example, when DataType="String", then ValueString key is required.
Refer to this table to discover appropriate data type for given drive condition property.
In most cases it will be String.
Required when DataType=String
Required when DataType=Double
Required when DataType=Int
Required when DataType=Bool