Skip to content

IoT Runtime Components Configuration#

The configuration file is a JSON structured file and it will be used by all components (Manager, Monitor, Controller, Driver). It allows the use of some tokens to be inserted depending on the context, those tokens are explained in the following table:

Name Type Usage Description
applicationName Application ${applicationName} The name of the current application
pid Application ${pid} The process id of the current application
componentId Application ${componentId} Name of the component running (AutomationManager, AutomationMonitor, AutomationController, DriverCsv, etc)
entityName Application ${entityName} The name of the context entity for the current application
tmp OperatingSystem ${tmp} User temporary directory
pwd OperatingSystem ${pwd} Running script location
cwd OperatingSystem ${cwd} Working directory (where the command is being executed)

Table: Connect IoT Configuration Tokens

Where the Configuration Lives#

MES holds the configuration of each Automation Manager: the one you set with Configure Automation Manager or, while the manager has none, the configuration entry /Cmf/System/Configuration/ConnectIoT/ConfigurationTemplate. The file on the manager host holds what the processes need to reach MES.

  • The package that Download creates has a config.json with the id, isMinimal set to true, and the system section, which holds the access token (see Connect IoT Administration). It also has config.full.json, a copy of the full configuration at the time of the download.
  • When isMinimal is true, the monitor reads the full configuration from MES each time it starts, keeps the local system section, and writes the result to config.downloaded.json next to config.json. Until then, the manager and the monitor log only to the console.
  • When the Automation Manager is saved in MES, the running monitor writes config.downloaded.json again. Controller and driver processes read that file when they start, so an instance takes the change at its next restart. The monitor takes it when it starts again, and the manager then reloads its logging settings.
  • When isMinimal is false or missing, the processes use the local file as it is, and changes in MES do not reach them.

Base Structure#

Name Type Default Value Description
id String Identifier of the process
monitorHost String "localhost" Address of the local monitor listener address
monitorPort Integer 0 Port of local monitor listener. 0 for automatic port assignment
cache String Local path where the packages will be downloaded and executed
monitorApplication String ""${pwd}\monitor.js" Complete path of the Monitor process
repository Repository Repository regarding packages handling
system System System access settings
storage Storage Section to configure persistency location
logging Logging Logging mechanism settings
monitor monitor Monitor process specific settings
controller controller Controller(s) process(es) specific settings
driver driver Driver(s) process(es) specific settings

Table: Connect IoT Base Structure

Repository Structure#

The repository represents the way the Monitor process handles the location where the packages are located (remote) and stored (local).

Name Type Possible Values Default Value Description
type String Npm
Directory
System
Type of repository
- Npm - uses an NPM server
- Directory - uses a local directory with the packages and a json-based database descriptor
- System - downloads the packages from MES (retrieves settings from the system structure detailed below)
settings Object Repository settings (depending on the type)

Table: Connect IoT Repository Structure

Type Npm Settings#

Name Type Default Value Description
url String URL where the NPM server is located (including port)
token String Optional Bearer token used for authentication

Table: Npm specific settings

Type Directory Settings#

Name Type Default Value Description
path String Directory where the packages are located. Must be accessible by process and currently, UNCs are not supported

Table: Directory specific settings

Directory Examples#

"repository": {
    "type": "Npm",
    "settings": {
        "url": "YourNpmAddress",
        "token": "YourNpmToken"
    }
}
"repository": {
    "type": "Directory",
    "settings": {
        "path": "[UserSelectedDirectory]\\MyDirectoryRepository"
    }
}

Storage Structure#

Name Type Possible Values Default Value Description
type String Directory Directory Type of persistency location
settings Object Storage type settings
settings\path String Base path where the persistency data will be stored.
OperatingSystem tokens are supported
settings\retentionTime Integer
string
"30d" Number of seconds to store the data. 0 means forever.
Supports string with a trailing token indicating the time unit:
s - seconds
m - minutes
h - hours
d - days
w - weeks (7 days)
settings\logMaxLength Integer 4096 Maximum number of characters displayed in the console when storing a value in storage. If the value exceeds this limit, it will be truncated for readability.

Table: Connect IoT Storage Structure

Storage Structure Examples#

"storage": {
    "type": "Directory",
    "settings": {
        "path": "[UserSelectedDirectory]/Persistency",
        "retentionTime": 3600,
        "logMaxLength": 4096
    }
}
"storage": {
    "type": "Directory",
    "settings": {
        "path": "[UserSelectedDirectory]/Persistency",
        "retentionTime": "10d",
        "logMaxLength": 0
    }
}

System Structure#

Name Type Default Value Description
tenantName String System Tenant name to use by the components
address String "localhost"
port Integer
timeout Integer
useSsl Boolean false
authentication Authentication Object

Table: Connect IoT System Structure

Authentication Structure#

Name Type Possible Values Default Value Description
type String SecurityPortal
ClientCredentials
Authentication type to use
settings Object Authentication settings (depending on the type)

Table: Authentication structure

Authentication type SecurityPortal settings#

Name Type Default Value Description
clientId String Id of the client accessing to (MES)
accessToken String Security Portal generated long term Access Token. To be set on non-interactive scenarios with Security Portal
openIdConfiguration String URL where the OpenId endpoint can be accessed. Example: http://YourEnvironment/tenant/YourTenant/.well-known/openid-configuration
applicationBaseUrl String Optional: In the case of apps, the Monitor will send requests to this address

Table: Authentication type SecurityPortal structure

Authentication type ClientCredentials settings#

Name Type Default Value Description
clientId String Id of the client accessing to (MES)
openIdConfiguration String URL where the OpenId endpoint can be accessed. Example: http://YourEnvironment/tenant/YourTenant/.well-known/openid-configuration
applicationBaseUrl String Optional: In the case of apps, the Monitor will send requests to this address
password String Optional: Password to login - Should not be used

Table: Authentication type SecurityPortal structure

Examples#

"system": {
    "tenantName": "YourTenant",
    "address": "YourEnvironment",
    "port": 8093,
    "timeout": 60000,
    "useSsl": false,
    "authentication": {
        "type": "SecurityPortal",
        "settings": {
            "clientId": "MES",
            "accessToken": "user created access token",
            "openIdConfiguration": "http://YourEnvironment/tenant/YourTenant/.well-known/openid-configuration"
        }
    }
}
"system": {
    "tenantName": "YourTenant",
    "address": "YourEnvironment",
    "port": 8093,
    "timeout": 60000,
    "useSsl": false,
    "authentication": {
        "type": "ClientCredentials",
        "settings": {
            "clientId": "MES",
            "openIdConfiguration": "http://YourEnvironment/tenant/YourTenant/.well-known/openid-configuration"
        }
    }
}

Logging Structure#

The logging configuration allows several different loggers to be configured at same time, meaning that for each type of logger, different options can be configured.

Name Type Possible Values Default Value Description
id String Identifier of the logger, if none is configured, only one of the same type is allowed
type String Console
File
Http
OTLP
Type of the transport
options Object Transport options,different for each type of transport, see each transport information below
applications Array of String AutomationMonitor
AutomationController
AutomationManager
DriverSecsGem
DriverOpcUA
DriverMqtt
DriverBle
DriverCsvFile
DriverRawFile
DriverKeyboardWedge
DriverOib
DriverOpcDA
DriverSerial
DriverTcpIp
A wildcard can configure all or filter by name, example: ’Driver*’

Table: Connect IoT Logging Structure

Common Transport Options#

These options apply to all types:

Name Type Possible Values Default Value Description
level String debug
info
warn
error
"info" Minimum level of messages that this transport should log. If infolevel is defined, all entries of level info, warn and error will be logged and debug entries will be ignored.
label String "${applicationName}" Label to append in the beginning of the log entry (if used in the format)
format String "${log.timestamp}${log.level}:${log.message}" Format of the line of the log
timestamp Boolean true Flag indicating if we should prepend output with timestamps. If function is specified, its return value will be used instead of timestamps
timestampFormat String "YYYY-MM-DD HH:mm:ss.SSS" Format of the timestamp in the log entry. Please refer to https://github.com/taylorhakes/fecha#formatting-tokens ↗ for full format information
maxLength Integer 0 Max length of the message entry to log (<=0 to ignore). If entry is larger than the value, will log (70% of the maxLength) of the start of the message and the last (30% of maxLength) characters. This setting is useful to keep huge communication logs in a more controllable state.
specificLevelLock Boolean false Only log the specified verbosity level. With this setting set to true the levels greater than the level will be ignored.
isEnabled Boolean true Is the Transport enabled

Table: Connect IoT Common Transport Options

Console Transport Options#

This transport log all the messages to the application console.

Name Type Default Value Description
colorize Boolean true Flag indicating if we should colorize output.
colorizeMessage Boolean true Is the colorization to apply to the full message or only the verbosity.

Table: Connect IoT Console Transport Options

Example#

{
    "type": "Console",
    "options": {
        "level": "debug",
        "prettyPrint": true,
        "colorizeMessage": true
    },
    "applications": [ "*" ]
}

File Transport Options#

As the name states, this transport log all the messages to the file system.

Name Type Default Value Description
frequency String A string representing the frequency of rotation. This is useful if you want to have timed rotations, as opposed to rotations that happen at specific moments in time. Valid values are '#m' or '#h' (e.g., '5m' or '3h'). Leaving this null relies on datePattern for the rotation times.
datePattern String "YYYY-MM-DD" A string representing the moment.js date format to be used for rotating. The meta characters used in this string will dictate the frequency of the file rotation. For example, if your datePattern is simply 'HH' you will end up with 24 log files that are picked up and appended to every day.
filename String "LogFile_${date}.log" Filename to be used to log to. This filename can include the ${date} placeholder which will include the formatted datePattern at that point in the filename
dirname String "." The directory name to save log files to
maxSize String "10m" Maximum size of the file after which it will rotate. This can be a number of bytes, or units of kb, mb, and gb. If using the units, add k, m, or g as the suffix. The units need to directly follow the number.
maxFiles String "30d" Maximum number of logs to keep. If not set, no logs will be removed. This can be a number of files or number of days. If using days, add d as the suffix
option Object { flags: 'a', mode: 0o777 } An object resembling https://nodejs.org/api/fs.html#fs_fs_createwritestream_path_options ↗ indicating additional options that should be passed to the file stream
auditFile String ${dirname}/.audit.json ​A string representing the name of the audit file.

Table: Connect IoT File Transport Options

File Transport Options Example#

{
    "id": "MyFileLogger01",
    "type": "File",
    "options": {
        "filename": "${applicationName}_${date}.log",
        "dirname": "${tmp}/YourManager01/Logs/${applicationName}",
        "level": "debug",
        "timestampFormat": "HH:mm:ss.SSSSS",
        "maxSize": "10m",
        "maxFiles": 5,
        "maxLength": 5000,
        "specificLevelLock": false
    },
    "applications": [ "AutomationMonitor", "AutomationManager" ]
}

HTTP Transport Options#

The HTTP transport is a generic way to log, query, and stream logs from an arbitrary HTTP endpoint, preferably winstond. It takes options that are passed to the node.js http or https request:

Name Type Default Value Description
host String "localhost" Remote host of the HTTP logging endpoint.
port Integer 80 or 443 Remote port of the HTTP logging endpoint.
path String "/" Remote URI of the HTTP logging endpoint.
auth Object None An object representing the username and password forHTTP Basic Auth.
ssl Boolean false Value indicating if we should us HTTPS

Table: Connect IoT HTTP Transport Options

HTTP Transport Options Example#

{
    "id": "MyHttp01",
    "type": "Http",
    "options": {
        "host": "localhost",
        "port": "80",
        "path": "logger",
    },
    "applications": [ "AutomationController" ]
}

OTLP Transport Options#

The OTLP transport is a transport to broadcast logs using the open telemetry standard. When the endpoint is not configured, it is discovered from the MES (see Default OTLP Endpoint):

Name Type Default Value Description
isEnabled Boolean Flag to enable the transport. If not set, it is derived from the host's observability configuration (see note below).
level String Logging Level.
isInternal Boolean False Flag only used if the automation manager is running in the same stack as the MES application.
endpoint String An external endpoint that receives and processes telemetry signals sent according to the OTLP (open telemetry protocol) format (i.e https://mytelemetrystack.com/telemetry/http). If not set, the telemetry address of the MES is used.
logsExportTimeoutMillis Integer Maximum time (in milliseconds) allowed for a log batch export to complete before it is considered failed. Falls back to the OTEL_BLRP_EXPORT_TIMEOUT environment variable, then to the OpenTelemetry SDK default, when not set.

Table: Connect IoT OTLP Transport Options

isEnabled inherited from host observability settings

When isEnabled is not explicitly set on the OTLP transport, the Automation Manager configuration derives it from the host's own observability configuration (the OBSERVABILITY_ENABLED environment variable and related settings). Set isEnabled explicitly to opt this transport in or out regardless of the host configuration.

Default OTLP Endpoint#

When an enabled OTLP transport has no endpoint, the Automation Monitor reads the telemetry address, services.telemetry, from the well-known configuration endpoint of the MES (/.well-known/criticalmanufacturing-configuration) when it authenticates. It then distributes the address to the Automation Manager, the Automation Controllers, and the drivers, including those that start or restart later.

  • An endpoint set on the transport always takes priority over the discovered address.
  • The discovered address must use http or https. If the well-known configuration endpoint cannot be reached, or does not return a valid telemetry address, the authentication with the MES fails.
  • The default Automation Manager configuration no longer sets an endpoint. In earlier versions it set http://traefik:8082/__internal/telemetry/http, which is not valid for every deployment. Remove that value from custom configurations that copied it, unless it is the collector you intend to use.

OTLP Transport Options Example#

 {
    "type": "OTLP",
    "options": {
        "isEnabled": true,
        "level": "debug"
    },
    "applications": [ "*" ] 
},

Monitor Structure#

The optional monitor section is specifically for the monitor process and are not used by the other applications.

Name Type Default Value Description
notifyBeforeKill Boolean true Flag indicating if a notification to the processes before killing them (allowing them to properly cleanup any resources, disconnect from devices, etc), or simply kill them.
killNotificationTimeout Integer 10000 Number of milliseconds to wait for the "about to be killed" process reply that it has finished the cleanup an is ready to be killed.
retryAttempts Integer 30 When calls protected by retry mechanism fail, number of executions before failing
sleepBetweenAttempts integer 1000 When calls protected by retry mechanism fail, time to wait between retries
processCommunication SslConfig Configuration to allow inter-process communications to be using SSL (monitor <-> controller(s) and monitor <-> driver(s))
otlp Object Settings for the proactive refresh of the OTLP access token before it expires. See OTLP Token Refresh Settings.
processHeartbeat Object Settings for the heartbeat that detects a controller or driver process that stops answering. See Process Heartbeat Settings.

Table: Connect IoT Monitor Structure

OTLP Token Refresh Settings#

The Monitor owns the OTLP access token refresh lifecycle: it caches the latest token received from the Host, proactively refreshes it before expiry, retries on failure, and distributes the refreshed token to the Manager and to the running Controller/Driver processes so that OTLP telemetry keeps flowing without needing Host activity to trigger a refresh.

Name Type Default Value Description
refreshBeforeExpirySeconds Integer 600 How many seconds before the access token's expiry the Monitor should proactively request a refresh.
retryAttempts Integer 60 Number of retries after a failed refresh attempt. Set to -1 to retry indefinitely.
retryDelaySeconds Integer 60 Number of seconds to wait between failed refresh retries.

Table: Connect IoT Monitor OTLP Token Refresh Settings

Process Heartbeat Settings#

The monitor sends a heartbeat to each controller and driver process that it runs on its host, every interval milliseconds. A process that does not reply within timeout counts one failure, and a reply resets the count. When the consecutive failures exceed allowedFailures, the monitor performs action. With the defaults, the action runs on the fourth failed heartbeat in a row.

Name Type Default Value Description
isEnabled Boolean true Flag indicating if the monitor sends the heartbeat. When false, no process is checked.
interval Integer 60000 Number of milliseconds between heartbeats. A value below timeout + 5000 is raised to that value.
timeout Integer 10000 Number of milliseconds a process has to reply to a heartbeat.
allowedFailures Integer 3 Number of consecutive failed heartbeats tolerated before the action. A negative value counts as 0.
action String Restart Restart kills the process so that it starts again. None only logs the failures. Any other value counts as None.

Table: Connect IoT Monitor Process Heartbeat Settings

The monitor log shows each failure as Process '<id>' (<name>) failed to reply the heartbeat (attempt # <n>/<allowedFailures>), and the action as Process '<id>' (<name>) exceeded the maximum amount of allowed failures. Performing action '<action>'. With the log level at debug, the controller and driver logs show Heartbeat received from Monitor for each heartbeat.

Monitor Structure Example#

"monitor": {
    "notifyBeforeKill": "true",
    "killNotificationTimeout": 30000,
    "retryAttempts": 45,
    "sleepBetweenAttempts": 1000,
    "processCommunication": {
        "useSsl": true,
        "privateKey": "YourCertificatesRepository\\key.pem",
        "certificate": "YourCertificatesRepository\\cert.pem",
        "certificateAuthority": "YourCertificatesRepository\\ca-cert.pem"
    },
    "otlp": {
        "refreshBeforeExpirySeconds": 600,
        "retryAttempts": 60,
        "retryDelaySeconds": 60
    },
    "processHeartbeat": {
        "isEnabled": true,
        "interval": 60000,
        "timeout": 10000,
        "allowedFailures": 3,
        "action": "Restart"
    }
}

Controller Structure#

The optional controller section is specifically for the controller(s) process(es) and are not used by the other applications.

Name Type Default Value Description
retryAttempts Integer 30 When calls protected by retry mechanism fail, number of executions before failing
sleepBetweenAttempts integer 1000 When calls protected by retry mechanism fail, time to wait between retries
profilerSessionsLocation string Location where the profiler sessions will be stored
contextManager string ZoneJs Context manager used to track asynchronous execution state across workflow tasks, so data belonging to the same zone stays correlated. Possible values are ZoneJs, which relies on Zone.js and offers the broadest compatibility, and Node, which relies on Node.js's native AsyncLocalStorage

Table: Connect IoT Controller Structure

Controller Structure Example#

"controller": {
    "retryAttempts": 45,
    "sleepBetweenAttempts": 1000,
    "profilerSessionsLocation": "YourControllerRepository\\tempController",
    "contextManager": "Node"
}

Driver Structure#

The optional driver section is specifically for the driver(s) process(es) and are not used by the other applications.

Name Type Default Value Description
retryAttempts Integer 30 When calls protected by retry mechanism fail, number of executions before failing
sleepBetweenAttempts integer 1000 When calls protected by retry mechanism fail, time to wait between retries
processCommunication SslConfig Configuration to allow inter-process communications to be using SSL (driver<-> controller)

Table: Connect IoT Driver Structure

Driver Structure Example#

"driver": {
    "retryAttempts": 45,
    "sleepBetweenAttempts": 1000,
    "processCommunication": {
        "useSsl": true,
        "privateKey": "YourCertificatesRepository\\key.pem",
        "certificate": "YourCertificatesRepository\\cert.pem",
        "certificateAuthority": "YourCertificatesRepository\\ca-cert.pem"
    }
}

SslConfig structure#

When communication between processes require SSL use these settings.

Name Type Default Value Description
useSsl Boolean false Use SSL communication on component communication
rejectUnauthorized Boolean false If not false a server automatically reject clients with invalid certificates.
Allows bypass of error: "Connection with monitor error: unable to verify the first certificate" on a completely unsecured way when set to false!
also, if we want to ignore environment variable "NODE_TLS_REJECT_UNAUTHORIZED=" we may set rejectUnauthorized: true
On self-signed certificates, we can pass the correct CA (certificate authority) certificate with certificateAuthority option
privateKey string PEM encoded SSL private key Value or file full path containing the key value
certificate string PEM encoded SSL certificate Value or file full path containing the certificate value
certificateAuthority string PEM encoded SSL custom certificate authority (CA) Value or file full path containing the certificate value

Table: Connect IoT SslConfig Structure

SslConfig Structure Example#

{
    "useSsl": true,
    "privateKey": "YourCertificatesRepository\\key.pem",
    "certificate": "YourCertificatesRepository\\cert.pem",
    "certificateAuthority": "YourCertificatesRepository\\ca-cert.pem"
}

SystemCertificate structure#

When communication between processes require SSL use these settings.

Name Type Default Value Description
rejectUnauthorized Boolean false If rejectUnauthorized is set to true, it will change the environment variable of the process 'NODE_TLS_REJECT_UNAUTHORIZED' to '1', if set to false or not set it default to '0'.
certificate string It will generate a temporary file and add the path to the environment variable of the process 'NODE_EXTRA_CA_CERTS'.
certificateAuthority string It will append to the certificate and generate a temporary file and add the path to the environment variable of the process 'NODE_EXTRA_CA_CERTS'. value

Table: Connect IoT SystemCertificate Structure

SystemCertificate Structure Example#

{
  "id": "MyManager",
  "cache": "[MyCacheLocation]/Cache",
  "hostName": "localhost",
  "monitorApplication": "${pwd}/monitor.js",
  "repository": {
    "type": "System"
  },
  "system": {
    "tenantName": "MyTenant",
    "address": "MyAddress",
    "port": 80,
    "timeout": 120000,
    "useSsl": false,
    "isLoadBalancingEnabled": false,
    "authentication": {
      "type": "SecurityPortal",
      "settings": {
        "clientId": "MES",
        "accessToken": "user access token",
        "openIdConfiguration": "http://MyAddress/SecurityPortal/tenant/MyTenant/.well-known/openid-configuration"
      }
    }
  },
  "isMinimal": false,
  "storage": {
    "type": "Directory",
    "settings": {
      "path": "[MyPersistencyDirectory]/Persistency",
      "retentionTime": "30d"
    }
  },
  "logging": [
    {
      "type": "Console",
      "options": {
        "level": "debug",
        "prettyPrint": true,
        "colorizeMessage": true,
        "isEnabled": true
      },
      "applications": [
        "*"
      ]
    },
    {
      "type": "OTLP",
      "options": {
        "level": "info",
        "isEnabled": false
      },
      "applications": [
        "*"
      ]
    },
    {
      "id": "Controllers",
      "type": "File",
      "options": {
        "filename": "${applicationName}_${date}.log",
        "dirname": "[MyLogsDirectory]/Instances/${entityNameNormalized}/${componentId}",
        "level": "debug",
        "timestampFormat": "HH:mm:ss.SSSSS",
        "maxSize": "10m",
        "maxFiles": "30d",
        "isEnabled": true
      },
      "applications": [
        "AutomationController"
      ]
    },
    {
      "id": "Drivers",
      "type": "File",
      "options": {
        "filename": "${applicationName}_${date}.log",
        "dirname": "[MyLogsDirectory]/Instances/${entityNameNormalized}/${componentId}",
        "level": "debug",
        "timestampFormat": "HH:mm:ss.SSSSS",
        "maxSize": "10m",
        "maxFiles": "30d",
        "isEnabled": true
      },
      "applications": [
        "Driver*"
      ]
    },
    {
      "id": "ManagerAndMonitor",
      "type": "File",
      "options": {
        "filename": "${applicationName}_${date}.log",
        "dirname": "[MyLogsDirectory]/Instances/Manager/${applicationName}",
        "level": "info",
        "timestampFormat": "HH:mm:ss.SSSSS",
        "maxSize": "10m",
        "maxFiles": "30d",
        "isEnabled": true
      },
      "applications": [
        "AutomationMonitor",
        "AutomationManager"
      ]
    },
    {
      "id": "Jobs",
      "type": "File",
      "options": {
        "filename": "Job_${jobId}_${date}.log",
        "dirname": "${temp}/ConnectIoT/Jobs",
        "auditFile": "${temp}/ConnectIoT/Jobs/.audit.json",
        "level": "info",
        "timestampFormat": "HH:mm:ss.SSSSS",
        "maxSize": "10m",
        "maxFiles": "30d",
        "isEnabled": true
      },
      "applications": [
        "AutomationJob"
      ]
    }
  ]
}