# ATLAS Product Suite
> Comprehensive technical documentation for Motion Applied ATLAS. Covering custom displays, data integration, APIs, and developer tools
Source: https://docs.atlas.motionapplied.com
Full text of the documentation, ordered by site navigation. Each
page is preceded by its title and canonical URL. Generated at build
time by hooks/llms_txt.py.
---
# Overview
ATLAS (Advanced Telemetry Linked Acquisition System) is more than just a telemetry tool—it's a modular, open, and scalable data ecosystem built to meet the evolving demands of motorsport and high-performance engineering. Whether you're a race team, OEM, or technology partner, ATLAS empowers you to capture, analyse, and act on data in real time and at scale.
## What is ATLAS?
ATLAS is a real-time data acquisition and analytics platform used across Formula 1, Formula E, IndyCar, NASCAR, and beyond. It enables teams to:
- Capture telemetry from hundreds of sensors in real time
- Distribute data across teams and tools via open APIs and streaming protocols
- Analyse performance using custom dashboards, overlays, and integrations with MATLAB, Python, and cloud-native platforms
## Why choose ATLAS?
- __Open by Design__
---
ATLAS offers an open, API-first architecture that integrates easily with existing tools and workflows.
- __Built for Performance__
---
It delivers fast startup, high-frequency data capture, and powerful visualisation tools trusted by elite motorsport teams.
- __Flexible Deployment__
---
ATLAS supports local, cloud, and hybrid setups with scalable storage and licensing options to fit any team size or budget.
!!! tip "Interested in how you can use ATLAS?"
If you're interested in how Motion Applied can advance your data systems, contact [sales@motionapplied.com](mailto:sales@motionapplied.com).
---
# Use Cases in Motorsport and Engineering
The ATLAS ecosystem is a powerful telemetry and data intelligence platform designed to support high-performance environments. Whether you're tuning a race car or validating aerospace systems, ATLAS provides the tools to ingest, analyse, and act on data in real time. Below are key use cases that illustrate how ATLAS is being applied across motorsport and engineering domains.
## Real-Time Telemetry for Competitive Edge in F1
In Formula 1, milliseconds matter. ATLAS enables teams to stream telemetry from ECUs, sensors, simulators, and wind tunnels with minimal latency. This real-time data flow allows engineers to monitor vehicle performance live during races or testing sessions.
Teams use ATLAS to:
- Stream live telemetry from ECUs, sensors, and gearboxes.
- Analyse powertrain and gearbox performance in real time.
- Securely share configuration files and telemetry across consortium members using RDA licensing and encryption.
This ensures consistent control across hardware generations and protects proprietary data while enabling collaborative development.
## Formula E and Extreme E: Sustainability and Simulation
ATLAS powers telemetry and control systems for Formula E and Extreme E, supporting electric powertrains and sustainable racing initiatives. Use cases include:
- Battery management and diagnostics.
- Integration with MATLAB/Simulink for predictive modelling.
- Remote access to telemetry for offsite analysis.
These capabilities help teams optimise energy usage and performance under strict sustainability constraints.
## NASCAR: Custom Telemetry Recorder and GPS Integration
ATLAS has been tailored for NASCAR with a dedicated telemetry recorder that supports Vector GPS data and custom configuration formats. Teams benefit from:
- Real-time location tracking and performance overlays.
- Streamlined data ingestion compatible with ATLAS visualisation tools.
This adaptation allows NASCAR teams to leverage ATLAS’s precision analytics in a high-speed oval racing context.
---
# Eco-System Overview
The ATLAS ecosystem is Motion Applied’s advanced telemetry and data management platform, purpose-built for high-performance motorsport engineering and adaptable to wider industries. It brings together powerful components for **hardware configuration, data distribution, storage, and visualisation**, ensuring that engineers can capture, process, and analyse telemetry data at speed and scale.
## System Monitor – ECU Configuration and Calibration
At the foundation of the ecosystem is **System Monitor**, the primary tool for configuring and calibrating ECUs (Electronic Control Units).
- Provides a multi-platform [Configuration API](../developer-resources/system-monitor/configuration_api/index.md), that enables seamless integration with client applications in various programming languages.
- Supports the creation of **virtual parameters**, which are translated into open formats for downstream use.
- Offers a secure and efficient environment for hardware configuration, serving as the **gateway between physical ECUs and the ATLAS data ecosystem**.
System Monitor ensures that hardware is correctly defined and calibrated before data is distributed, making it the cornerstone of telemetry workflows in motorsport and other high-performance applications.
## Distribution – ATLAS Data Server, Bridge Service, and Stream API
Telemetry flows through ATLAS using a set of tightly integrated services:
- [**ATLAS Data Server (ADS)**](../key-functionality/stream/ads/index.md)
Acts as the central hub for telemetry ingestion and distribution. ADS records live sessions, manages multicast delivery, and supports daisy-chaining across servers. This enables remote telemetry architectures, where distributed teams can access live data with no loss of performance.
- [**Bridge Service**](../key-functionality/stream/open_streaming_architecture/index.md/#bridge-service)
Real-time data is processed and distributed using modern broker technology (e.g., Kafka), replacing legacy multicast methods. This service ensures reliable, scalable delivery and supports cloud deployments. Engineers can also create calculated signals derived in real time—that are published back into the stream for consistent downstream use.
- [**Stream API**](../developer-resources/secu4/stream_api/index.md)
Exposes telemetry in a standardised, engineering-calibrated format using Google Protobuf. The API provides interfaces for both data producers and consumers, enabling seamless integration with external tools and workflows. The Bridge Service further enhances this by converting raw telemetry into usable engineering values while decoupling broker technology.
## Data Storage – SQL Race Sessions and Parquet Sessions
ATLAS supports flexible storage of telemetry data in two complementary formats:
- [**SQL Race**](../key-functionality/store/sqlrace/index.md)
A session-based database optimised for motorsport workflows. SQL Race enables rapid querying and analysis of session data, making it a proven choice for race engineering environments.
- [**Parquet**](../key-functionality/stream/open_streaming_architecture/index.md#historical-data-storage-parquet)
A modern, columnar format optimised for big data analytics. Parquet sessions are well-suited for integration with external platforms, cloud pipelines, and long-term storage. Files can be exported at configurable intervals, with optional encryption for secure distribution.
Together, these formats allow users to work within established motorsport practices while also taking advantage of scalable, analytics-driven workflows.
## [Visualisation – ATLAS Viewer](../key-functionality/analyse/viewer/index.md)
At the user-facing end of the ecosystem, the ATLAS Viewer provides powerful tools for real-time visualisation and post-session analysis:
- Live streaming of telemetry alongside historical playback
- Flexible plotting, overlays, and comparisons across multiple sessions
- Integration with external models and simulation data
- Support for multiple data formats
This combination of performance, flexibility, and usability makes ATLAS Viewer the engineer’s primary workspace for turning raw telemetry into actionable insight.
---
# Ecosystem Guide
Not sure where to start? This guide will help you find the right ATLAS components for what you're trying to do. No prior knowledge of the software needed.
ATLAS is an ecosystem for working with telemetry data - the measurements that come from sensors, controllers, and simulation in high performance engineering environments.
``` mermaid
graph LR
A["Configure"] --> B["Stream"]
B --> C["Store"]
B --> E["Enrich"]
E --> B
B --> D["Analyse"]
```
| Stage | What Happens | Example |
|-----------|-----------------|------------|
| [Configure](../key-functionality/configure/system-monitor/index.md) | Setup hardware so it knows what to measure | Defining which sensors to log on an ECU |
| [Stream](../key-functionality/stream/index.md) | Move live data from hardware to software | Telemetry flowing from a car to the pitwall |
| [Enrich](../key-functionality/enrich/index.md) | Run models or calculations on data to create parameters | Running a Simulink aero model against live telemetry |
| [Store](../key-functionality/store/index.md) | Save live data for later use | Archiving a race session for post-event review |
| [Analyse](../key-functionality/analyse/index.md) | Visualise and explore the data | Overlaying two laps to find where time was lost |
## Storing Data
There are two broad choices: files or databases. They are not mutually exclusive, some teams will use both but at different stages.
=== "Files"
Self contained data files on disk. Copy, email, upload, put them on a USB stick. No server required.
Pick files when:
- Portability matters when you're sharing data with someone without access to your internal IT infrastructure
- You frequently work offline with just a laptop
- Batch processing is part of your workflow
- Long time archiving on a network drive or S3 bucket is cheaper than keeping a database running
- Interoperability
!!! tip "Which format?"
- SSN2 is ATLAS-native file with full session fidelity. Use when data is staying in the ATLAS ecosystem.
- CSV is the universal fallback, any tool will work with CSV. But it's large and slow for big data sets and some configuration is necessary.
- MATLAB is best if you frequently run models using Simulink and have control-system workflows.
- Parquet is best for analytics, data science and cloud pipelines. Some configuration is needed to work with ATLAS.
=== "SQL Race Database"
A purpose built database layer ontop of SQL Server or SQLite. Manage sessions, configuration and data.
Pick SQL Race Database when:
- You are capturing data from sensors in real-time
- You need to browse, filter and sort sessions by metadata instead of folder structures
- A team of engineers need concurrent access to the same session
=== "Other Database Structure - RTA"
RTA is an architectural API layer that sits between ATLAS and any existing data store.
Pick RTA when:
- You already have your databases setup, with data and want to avoid a migration to SQL Server
- You want flexibility of scaling and integration with other Cloud services
- There are many other tools in your data pipeline that need to query the same data source
## Data Distribution
When you need to get data from physical systems to downstream clients.
=== "ADS + RDS"
The traditional ATLAS live data path. ADS accepts incoming telemetry (either by wirelink, radio or ethernet) and multicasts to downstream clients on the same local network.
Pick when:
- You need low-latency live data on a local network
- Data is coming directly from physical systems or vehicles
- Downstream consumers are on the same LAN
- You want a simple, proven live telemetry path
- You do not need cloud distribution or long-term buffering
- Consumers are expected to be online at the same time as the data source
=== "Open Streaming"
A Kafka-based streaming layer that decodes raw data from ADS and publishes it to defined Kafka topics.
Pick when:
- You need to read or write data on Kafka
- You want to decouple producers and consumers
- Data needs to be consumed by multiple independent downstream systems
- You are building event-driven, scalable, or cloud-based architectures
- You need replayability or durable streams
- Consumers may be remote, offline, or join later
- You want to ingest third party data sources
=== "RTA"
A websocket interface for session data. Data can be buffered through Redis so clients can join at any point.
Pick when:
- You need to distribute session-based data in near real time
- Clients need to join late and still receive buffered data
- You want a browser- or UI-friendly interface (WebSockets)
- You are supporting visualisation tools or dashboards
- Kafka is not required, but live-ish access is
- You want controlled fan-out without full streaming infrastructure
=== "Local File Share"
Local files that can be sent manually to team members or uploaded to a network drive.
Pick when:
- Data volumes are small or manageable
- Real-time access is not required
- You need manual review or ad-hoc sharing
- Consumers are humans, not systems
- You want the simplest possible distribution mechanism
- The workflow is offline, asynchronous, or low frequency
## Calculated Channels
When you need to compute derived parameters.
=== "FDL"
Built in expression language for ATLAS Viewer.
Pick when:
- Your calculations are simple and can be achieved with standard mathematical operations.
=== "C# .NET Functions"
Custom functions written in C# can be embedded in XFN or compiled into a DLL.
Pick when:
- You have existing C# functions you wish to reuse without rewriting
- You need advanced Object Oriented Programming functionality
- You require multiple function outputs
=== "MATLAB Functions"
Custom functions defined via .XFN that delegates execution to a MATLAB script.
Pick when:
- You have existing MATLAB functions you wish to reuse without rewriting into FDL
- You want to use native MATLAB functionality to process complicated mathematical equations.
=== "vTAG Server"
Software application that executes Simulink models against data, producing parameters that appear in ATLAS Viewer.
Pick when:
- You have Simulink models that you want to run
- You have hardware running physically and you wish to augment by adding software modelling ontop
- You wish to standardise models and ensure all downstream clients have the same virtual outputs
- You are running an ADS setup
=== "Virtual Parameter Service"
Microservice that can be deployed alongside Open Streaming to move calculations downstream of clients.
Pick when:
- You want to co-ordinate consistency with virtuals from a centralised location separate from each client
- You need to monitor the throughput of virtual processing
- You require performant calculation of virtual parameters separate from the load of downstream clients
- You are running the Open Streaming Architecture
## Programmatic Access
When you need to read, write or manipulate your data either from inside or outside of the ATLAS Ecosystem.
=== "SQL Race API"
For reading, writing and managing session data.
Pick when:
- You do NOT need to automate ATLAS interactions.
- You need to extract session data, regardless of session type
- You do NOT need to load the session into ATLAS.
- You want a direct, simpler integration focused on SQLRace session handling without UI or automation complexity.
!!! tip "Supported session formats"
- SSN
- SSN2
- SQL Race Session
=== "Automation API"
For controlling the UI of ATLAS Viewer programmatically.
Pick when:
- You need to automate ATLAS interactions.
- You need to load session data into ATLAS.
- The workflow involves programmatic control of ATLAS actions, such as loading or manipulating sessions.
!!! tip "Supported session formats"
- SSN
- SSN2
- SQL Race Session
=== "Display API"
For creating custom display plugins in ATLAS Viewer.
Pick when:
- You need to automate ATLAS interactions and
- You want to add custom displays (visualization or UI enhancements).
=== "Stream API"
For interfacing with the Kafka broker.
Pick when:
- You are using Kafka
- You need live or continuous data streams
- You need to consume data from Kafka topics
- You need to publish data into Kafka topics
- You are building event-driven or real-time systems
!!! tip "Support Library"
Support library is recommended to be used instead of the Stream API directly as it provides many helpful wrappers which can be used to simplify the process of interfacing with the broker.
---
# Quick Start
This page contains quick access to getting started with different component in the ATLAS ecosystem.
## Software Installation Guides
| Component | Description |
|--------------|-------------|
| [ATLAS Viewer](../key-functionality/analyse/viewer/quick-start.md) | Visualise an analyse telemetry data. Open session files, build custom workbooks and compare runs. |
| [vTAG Server](../key-functionality/enrich/vtag/getting-started.md) | Run Simulink models against live or historical telemetry. Derive new parameters without hardware changes. |
| [ATLAS Data Server](../key-functionality/stream/ads/installation.md) | Distribute live telemetry across your network. Connects hardware to ATLAS clients over Ethernet or Wi-Fi. |
| [System Monitor](../key-functionality/configure/system-monitor/getting-started/index.md) | Configure, calibrate and tune Motion Applied ECYs. Program units, setup logging and manage sensors. |
| [SQL Race Management Studio](../key-functionality/store/sqlrace/installation.md) | Store and manage telemetry session in a central database. Bulk import, organise and share data across your team. |
| [Standalone Stream Recorder](../key-functionality/analyse/standalone-stream-recorder/index.md) | Record live Stream API telemetry to SSN2 files or a SQL Race database, without running ATLAS Viewer as the recorder. |
## Developer Guides
| Component | Description |
|--------------|-------------|
| [SQL Race API](../developer-resources/atlas/sql-race/integration.md) | Read and write telemetry sessions, parameters, events and laps directly |
| [Display API](../developer-resources/atlas/display-api/initialization.md) | Build custom display plugins that run natively in side ATLAS Viewer |
| [Automation API](../developer-resources/atlas/automation-api/getting-started.md) | Control ATLAS Viewer programmatically - load sessions, navigate displays and extract data. |
| [Stream API](../developer-resources/secu4/stream_api/reference_docs/getting-started/installation.md) | Read and write to the live telemetry stream over gRPC and Protbuf. |
| [Support Library](../developer-resources/secu4/support_library/index.md) | Helper library built ontop of the Stream API for building services. |
| [Configuration API](../developer-resources/system-monitor/configuration_api/index.md) | Configure ECUs programmatically via a cross-platform gRPC interface. |
| [Remote Telemetry Architecture](../developer-resources/rta/downloads.md) | Connect ATLAS to any existing database. Write a light weight data adapter and serve telemetry over REST. |
---
# Security
One of the key mechanisms used to protect customer data is RDA (Restricted Data Access). This system ensures that sensitive telemetry and operational data is only accessible to authorised users, maintaining confidentiality and compliance across all environments.
## What is RDA?
RDA is a security layer within ATLAS that governs access to protected data streams. It acts as a gatekeeper, filtering telemetry and system data based on user permissions. If a user or team does not have the appropriate access rights, the data is automatically discarded before it reaches them—ensuring that sensitive information remains secure and unseen.
## How RDA Protects You
**Access Control:** RDA enforces strict access policies, allowing only authorised personnel to view or interact with protected data.
**Data Filtering:** Data streams are filtered in real-time by ATLAS bridge services. Any data tagged with RDA protection is excluded from delivery to unauthorised endpoints.
**Third-Party Encryption Support:** RDA can be extended to support encryption from external sources, adding an additional layer of protection for integrated systems.
## Why It Matters
Whether you're monitoring system performance, analysing telemetry, or integrating with external platforms, RDA ensures that your data remains protected. It’s part of our commitment to delivering secure, scalable, and trustworthy solutions for every customer.
---
# System Requirements
## Operating System
* Windows 11 Professional or Enterprise (64 bit)
## Recommended Hardware
* 16 GB RAM or higher
* Quad-core Intel Core i7 or equivalent
* Dedicated GPU - NVidia Quadro M1000M or better
## Virtual Environments
ATLAS will run on Server VMs with Remote Desktop.
Enable GPU support where possible:
* [VMWare](https://www.dell.com/support/article/uk/en/ukdhs1/sln288103/how-to-enable-a-vmware-virtual-machine-for-gpu-pass-through?lang=en)
* [Hyper-V](https://docs.microsoft.com/en-us/windows-server/virtualization/hyper-v/deploy/deploying-graphics-devices-using-dda)
* [Citrix](https://www.citrix.com/content/dam/citrix/en_us/documents/go/reviewers-guide-remote-3d-graphics-apps-part-2-vsphere-gpu-passthrough.pdf)
---
# Overview
ATLAS (Advance Telemetry Linked Acquisition System) is a powerful software platform used to collect, process, and visualise data—especially in high-performance environments like motorsport. But don’t worry: you don’t need to be an engineer to get started. This guide walks you through the essentials.
!!! tip "Tips for New Users"
- Start with a simple session file and explore the display tools.
- Don’t worry about acronyms, focus on what you want to see or understand.
- ATLAS is modular, learn one part at a time.
## Core Concepts
### 1. The Journey of Data
ATLAS is built around the idea that data flows through a journey—from being captured, to being stored, to being visualised. ATLAS provides tools for each step:
- Capture: Collect data from sensors, simulations, or control units.
- Store: Save that data in structured formats for later use.
- Visualise: Display and analyse the data to make decisions.
### 2. Getting Started
When you first open ATLAS, you’ll typically:
- Load a historical session file (often called an .ssn file).
- Build a display to view the data—think of this like setting up your dashboard.
### 3. Distribute and Capture
This part of ATLAS helps you:
- Connect to hardware like ECUs (Electronic Control Units).
- Export and import configuration files.
- Use vTAG, a tool that lets you run virtual models (e.g. from Simulink) and view the results in ATLAS.
### 4. Process and Analyse
ATLAS supports:
- Real-time data streaming.
- Replay of past sessions.
- Integration with tools like MATLAB or Python for deeper analysis.
You can also compare multiple sessions side-by-side to spot trends or issues.
### 5. Store and Share
Data can be stored in:
- SQL Race: A database system for large-scale data storage.
- SSN2 files: Local files for quick access.
You can use SQL Race Management Studio to manage and share data across teams.
### 6. Visualise
ATLAS gives you full control over how data is displayed:
- Drag-and-drop interface to build custom dashboards.
- Zoom, pan, and overlay data from different sources.
- Use colour coding and annotations to highlight key events.
## Tools You’ll Encounter
ATLAS includes a set of tools that work together to help you collect, analyse, and visualise data—each one designed for a specific part of your workflow. Here's a quick guide to what they do and when to use them.
| Tool | What It Does | When to use it |
| -------- | ------- | ------- |
| [System Monitor](configure/system-monitor/index.md) | Manages projects and hardware connections | When programming ECUs |
| [ADS](stream/ads/index.md) | Connects ATLAS to live data sources | When streaming live data from a vehicle or simulator |
| [vTAG](enrich/vps/index.md) | Runs virtual models and integrates results | When running Simulink models with real-world data |
| [SQL Race](store/sqlrace/index.md) | Stores and manages large datasets | For persistent storage |
| [ATLAS](analyse/viewer/index.md) | Lets you create custom workbooks to visualise data | For visualising data in different displays |
---
# Overview
System Monitor is a software application for interfacing with Electronic Control Units (ECUs) and related systems. It supports trackside support, unit optimisation, dyno testing, development, and production. The application is optimised for Motion Applied systems but can be adapted for third-party controllers with hardware modifications.
## Key Features
**ECU Program Management**
- Upload and download ECU program files.
- Ensure the latest program versions are available.
**Tuning**
- View and modify editable ECU parameters.
- Apply changes instantly (Live Tune) or offline.
- Supports automatic tuning with a Testbed.
**Parameter Information Display**
- Monitor measurement parameters for live feedback.
- Access real-time data for diagnostics.
**Data Logging Configuration**
- Set up and manage data logging on TAG ECUs.
- Customise logging for specific needs.
**Sensor Configuration**
- Calibrate sensors and actuators connected to the ECU.
- Configure the DATALab system for advanced sensor management.
!!! note
Some features may require hardware modifications for third-party controllers.
---
# Overview
This guide helps you install and start using System Monitor. Below are the minimum and recommended system requirements:
| Component | Minimum | Recommended |
|-------------------|-------------------------------|-------------------------------|
| **Processor** | Intel Core Duo 2 GHz | Intel Core i7 Processor |
| **Memory** | 1 GB | 8 GB or higher |
| **Disk Space** | HDD with 200 GB free space | High capacity SSD 512 GB+ |
| **Operating System** | Windows 10 | Windows 10 |
| **Installation/Data Transfer** | CD-ROM drive, FTP site | CD-ROM drive, FTP site |
| **Power Supply** | Rapid battery recharge recommended (not trickle charge) while applications are running | Rapid battery recharge recommended (not trickle charge) while applications are running |
## 1. Install System Monitor
Download the System Monitor installer from the [Motion Applied Portal](https://portal.mclarenapplied.com/portal/Downloads/Software#System%20Monitor) and run the .msi file to begin the installation.
Three installation types are available:
- **Typical:** Installs all files for supported ECUs.
- **Custom:** Choose which components to install.
- **Complete:** Installs all files.
System requirements are checked during installation (memory, disk space, processor). Default install directory:
`C:\Program Files\McLaren Electronic Systems\System Monitor 8`
System Monitor icons are added to the default program folder: `\System Monitor\`
You may be prompted to restart your computer after installation.
### Custom Installation
Custom Installation lets you select components to install. Default settings match Typical Installation for first-time installs. Changed settings are remembered for future installations.
Available options:
- **Program Files:** System Monitor, CA-Card embedded code, TAGASAP conversion utility, SaxBasic.
- **Help Files:** Install help system.
- **Registry:** Modify Windows® Registry for licences and bases.
- **Device Drivers:** Install drivers for hardware devices (e.g., CA-Card).
- **DESKey Dongle Drivers:** Install drivers for DK2 USB, Parallel, and Network dongles.
- **VE-82 Drivers:** Install drivers for VE-82 Pot Board (run `USBDriverInstaller.exe` manually after installation).
## 2. Insert Your CA-Card or Licence Dongle
System Monitor can be licensed by:
- Communications adapter card (CA-card)
- Dongle
- Network card address
### Adding a Licence
Open the Add Licence dialog via **Help > Add Licence** or **Add Licence** in the Licence Required dialog.
!!! note
Later versions use a Licence File stored locally, defining teams and options. Licences are managed online at [Motion Applied Portal](https://portal.motionapplied.com/).
The window lists added devices (type and serial number). Select a device to view its licence profile.
- **Add New:** Browse for Licence Files.
- **Remove:** Remove selected licence.
- **Export:** Export the licence file.
- **Devices:** List connected devices.
- **Detect:** Search for accessible devices.
- **Active Team:** Select from the drop-down list.
- **Licence Details:** View licence profile summary.
Applications listed under a team are unrestricted for that team.

## 5. Start System Monitor
## 6. Select a Multi-Application Base or Configure a Unit.Def File
Customer bases control file access to prevent incorrect ECU programming. Associate customer bases with a project using a Multi-Application base.
- Select **File > Select Base**.
- Choose a Multi-Application Base and click **OK**.
## 7. [Create a New Program Version for Each Customer Base](../projects/program-data-versions.md)
Define Program and Data Version files for each Application in the Multi-Application Base.
- Select **File > New**.
- In the dialog, select **Program Version** and click **OK**.
- Choose files to include in the Program Version.
## 8. [Create a Project](../projects/file-operations.md)
A Project links all files needed to work on an ECU.
- Select **File > New**.
- Choose **Project** and click **OK**.
- Complete the sequence of dialog boxes to define the Project, connection method, Desktop filename, and Program Version for each Customer Base.
## 9. [Connect to the ECU](../projects/ecu-communication.md)
Manage the ECU connection the project uses.
- Select **ECU > Connect**.
- Choose the connection method (IP, HDLC, CAN).
- Click **Connect**.
---
# RDA
The Reduced Data Access feature of System Monitor lets teams restrict sharing of data and setups between engine and chassis applications. Access is determined by the team's licence and can be one of three states:
- `FullAccess`
- `RestrictedAccess`
- `NoAccess`
If a team has restricted access to an application, parameters within that application are locked unless they appear on the Parameter Unlock List (PUL). Locked parameters remain stored in session data so users with full access can still view them; they are either visible or invisible. Teams with restricted access cannot add a locked parameter to the Desktop or view/edit its Properties.
## Team Security
Team Security is a feature that prevents unauthorised users from accessing data associated with a team. Each team has a unique Team ID which is part of the licence file. More than one team is available for selection as the Active Team and can be changed at any time from the Licence Manager dialog.
Team Security can be disabled for a specific Data Version by selecting: **File > Save as** and selecting the Disable Team Security check box in the dialog box.
When connecting to an FIA Standard ECU, System Monitor verifies the Team ID of the Active Team. If the Team ID is valid, team functionality is enabled, System Monitor operates normally, and ECU tuning is permitted.
If verification fails, ECU tuning is blocked until a **Clear and Reprogram** command is performed. Click **Yes** to clear and reprogram the ECU. After reprogramming, a clear logging command is sent to the ECU. Once the connection is re-established, the Team ID is validated and ECU tuning becomes available.
If **No** is selected, access to the following commands is restricted:
- ECU Online
- ECU Live Updates
- ECU Auto Tune
- ECU Single Message
## Licensing
Access to data is controlled by the licence management scheme. Each licence is a file stored on the local machine. Application qualifiers inside the licence file determine which applications a team has:
- Full access to
- Restricted access to
- No access to (shown by prefixing the application name with `Locked:`)
!!! note
New licences are requested and generated online on the [Motion Applied Portal](https://portal.mclarenapplied.com/). Authorised users can request System Monitor and ATLAS licences, select a licence profile (teams, application access, ActiveX, etc.) and download the generated licence file.
## Parameter Unlock List (PUL)
Each application has an associated Parameter Unlock List (PUL) containing parameters that teams with Restricted Access may access. Teams with Full Access can edit the PUL to add or remove parameters. PUL access is provided from the Unlock List Management tab of the Application Properties dialog.
## On loading a .dtv
When a DTV is saved, a checksum of the PUL is stored in the file header. On loading a `.dtv` the stored checksum is compared with the checksum of the PUL on disk:
- If the user is not authorised for Full Access:
- If the checksums match: the appropriate parameters are unlocked.
- If the checksums do not match: the user is prompted to locate an alternative PUL.
- If no PUL file is found: all parameters for that application remain locked.
- If the user is authorised for Full Access: no checks are made and all parameters are unlocked.
Further team security is provided to prevent Data VersionFiles (.dtv) being loaded by other teams. Data Version files contain a list of Team IDs which are verified upon loading. The Data Version file will not load unless a valid Team ID is detected.
## Locked Parameters
Teams with Restricted Access see parameter icons with a locked symbol superimposed (for example, a locked Measurement Parameter in the Explorer).
Locked parameters are not removed from display windows they were previously added to — they are simply invisible. In a display window a locked icon appears in the status column and `-` is shown in the value column.
---
# Overview
System Monitor is a software tool used for real-time data monitoring, parameter editing, and logging in motorsport applications. It interfaces with ECUs and other data sources to provide engineers with flexible visualisation and control.
## Features
- Real-time acquisition and display of measurement data
- Editing of calibration parameters
- Customisable desktop layout with multiple window types
- Logging and export of data
- Integration with Data Wizard and other analysis tools
---
# Menus
| Menu | Description | Shortcut |
|---|---|---|
| File | Work on Project files. Includes printing. | ALT+F |
| Edit | Work on parameters and their values. Includes Parameter Explorer commands. | ALT+E |
| View | Control the appearance of the Desktop. | ALT+V |
| ECU | Work with ECUs. Shown when a Project is open. | ALT+U |
| Logging | Work with logging configuration. Shown when a Project is open. | ALT+L |
| Tools | Access additional tools within System Monitor. | ALT+T |
| Data Wizard | Work with Data Wizard. Shown when a Project is open. | ALT+W |
| Desktop | Create and edit Pages and Windows. Shown when a Project is open. | ALT+D |
### File Menu
Options to manage files and projects.

### Edit Menu
Options to edit projects and parameters.

### View Menu
Options to enable and disable different displays and toolbars.

### ECU Menu
Options to interact with the connected ECU.

### Logging Menu
Access logging configuration and controls.

### Tools Menu
Options to access additional tools.

### Data Wizard Menu
Access to Data Wizard features. Data Wizard compares the contents of the Edit Buffer with one or more previously created Data Versions, known as Candidate Data Versions. Using the Merge facility parameters in the current Data Version can be overwritten with those in the Candidate Data Versions.

### Desktop Menu
Options to customise the desktop layout. A Desktop consists of one or more pages that contain Windows. Every Project has a Desktop associated with it. Any Project can use any Desktop in the Multi-Application Base but can only have one Desktop loaded at any one time.

---
# Windows and Parameters
## Windows
System Monitor supports multiple window types for displaying and interacting with parameters.
### Editable Windows
Used to view and modify calibration parameters. These windows display parameter names, current values, units, and status indicators. Changes can be made directly in the value fields.
Each type of Editable Parameter has a specific type of Window. The following types of Editable Parameter are supported:
- Scalar
- 1-axis map
- 2-axis map
- Array
- String
### Measurement Windows
Used to monitor real-time data from sensors and ECUs. These windows can display values numerically or graphically (e.g. strip charts, bar graphs).
The data from Measurement Parameters can be displayed in the following types of display:
- Big Number
- Numeric
- Bar Graph
- Oscilloscope
- Grid
### Creating Windows
New windows can be created via the Desktop menu. Users can choose the window type and assign parameters during creation.
### Window Properties
Each window has configurable properties:
- **Title**: Custom name for the window
- **Colours**: Background and text colour settings
- **Axis Settings**: For graphical windows, axis ranges and labels can be defined
- **Update Rate**: Determines how frequently data is refreshed
### Window Types
- **Numeric Display**: Shows parameter values in a grid
- **Strip Chart**: Plots values over time
- **Bar Graph**: Displays values as vertical bars
- **Gauge**: Simulates analogue gauge behaviour
- **Status Indicator**: Shows boolean or state-based parameters
## Parameters
Parameters are central to System Monitor’s functionality. They are either editable (calibration) or measurement (read-only):
- Editable Parameters
The information used by the embedded control system in the ECU to control its performance. Also known as Configurable or Tune data. Examples are: fuel injection quantity look-up tables; engine idle speeds; ignition maps; etc. Tuning is the process of optimising the values of Editable Parameters
- Measurement Parameters
The information gathered by the ECU from sensors or generated by its own operation. Also known as On-Line information. Examples are: engine speed; water temperature; etc. Logging or Data Acquisition is the process of obtaining this information. System Monitor includes tools to control Logging.
### Editable Parameters
Any aspect of an ECU that can be changed in System Monitor is made available as an Editable Parameter. The type of Parameter is defined in the ASAP file by the ECU manufacturer. The ASAP file also permits or prevents System Monitor from changing the values of the Parameter. Editable parameters can be modified and sent to the ECU. They include:
- **Name**
- **Current Value**
- **Units**
- **Limits**
- **Status** (e.g. locked/unlocked)
Changes are made in editable windows and transmitted via the ECU menu.
### Measurement Parameters
Any item of data that can be reported by the ECU, is available in the form of a Measurement Parameter. All Measurement Parameters are treated the same in System Monitor but they can be grouped according to their source.
### Parameter Properties
Each parameter includes metadata:
- **Data Type**: Integer, float, boolean, etc.
- **Units**
- **Conversion**: Raw to engineering units
- **Update Rate**
- **Display Format**
### Virtual Parameters
A Virtual Parameter is a Measurement Parameter whose value is the result of applying mathematical operations to one or more existing Measurement Parameters.
For example, a differential pressure parameter may be created from the difference of two absolute pressure values. These are useful for derived metrics or combining multiple inputs.
### Parameter Explorer
A tool for browsing all available parameters. Supports filtering by name, type, and source. Parameters can be dragged into windows for display or editing.
---
# Configuration and Advanced Settings
## Configuration
System Monitor allows users to customise the desktop layout, window behaviour, and display settings.
### Desktop Layout
Windows can be arranged freely across the desktop. Users can:
- Create multiple pages to organise windows by function
- Save and load desktop configurations
- Cascade or tile windows for visibility
### Pages
Pages act as tabs or layers within the desktop. Each page can contain a unique set of windows. Useful for separating calibration, diagnostics, and logging views.
### Fonts
Font size and style can be adjusted globally or per window. This improves readability, especially in high-density layouts.
### Axis Properties
Graphical windows (e.g. strip charts) allow axis configuration:
- **Range**: Set min/max values
- **Labels**: Custom axis labels
- **Scaling**: Linear or logarithmic
### Conversion Properties
Parameters may require conversion from raw values to engineering units. Conversion settings include:
- **Scaling factors**
- **Offsets**
- **Lookup tables** (if supported)
## Advanced Tools
### Shortcuts
System Monitor supports keyboard shortcuts for common actions:
- **Ctrl+S**: Save desktop
- **Ctrl+L**: Start/stop logging
- **Ctrl+E**: Open parameter explorer
Shortcuts can be customised in the settings menu.
### Mathematical Operators
Used in virtual parameters and data analysis. Supported operators include:
- Basic arithmetic: `+`, `-`, `*`, `/`
- Logical: `AND`, `OR`, `NOT`
- Comparison: `>`, `<`, `==`
### Number Formats
Parameters can be displayed in various formats:
- Decimal
- Hexadecimal
- Scientific notation
Format is set per parameter or window.
### Parameter Unlock List
Some parameters are locked by default. Unlocking requires appropriate permissions and may involve entering a password or key.
### Advanced Settings
To open Advanced Settings, go to **Tools > Advanced Settings**. Some settings take effect
immediately, some require reconnecting to the ECU, and some require restarting System Monitor —
this is called out per setting below. Settings are grouped by area to make them easier to find.
!!! note "Version note"
Settings and defaults below reflect System Monitor 8.87.2. If you are running an older
version, a setting's default may differ from what is shown here.
#### Startup and project behaviour
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Enable Multiple Instances | Y / N | Allow multiple instances of System Monitor to run simultaneously on the PC. | Y | No |
| Open most recently used project | Y / N | Open the most recently used project when System Monitor starts. | N | No |
| Go online when opening project | Y / N | Put the ECU On-Line automatically when a project is opened. | N | No |
| Warn if Program Versions do not match | Y / N | If Y, a mismatch prevents ECU being put On-Line and shows a message box; if N the message is ignored. | N | No |
| Prompt for unit connection on opening project | Y / N | If N, automatically attempt connection to the last unit connection used for the project. | Y | No |
| Enable livetune on opening project | Y / N | If Y, start livetune immediately after project open and unit connection. | N | No |
| Default Explorer display to collapsed view | Y / N | If Y, the Parameter Explorer starts collapsed instead of expanded. | N | No |
#### Data versions and team security
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Search base for versions | Y / N | Controls search base for versions (see ECU Search). | N | No |
| Format data version text | Y / N | Control formatting of data version text (see ECU Bar). | N | Restart |
| Enable Data Version Security | Y / N | Enable Team Security globally for data versions. | Y | No |
| Directory for Parameter Unlock List files | Path | Directory used to list parameters accessible by restricted teams. Leave blank to use System Monitor's default location. | (blank) | No |
| Search base for non-active versions | Y / N | When N, multi-application base is not searched for non-active application DTVs. | Y | No |
| Enable Parameter Offset | Y / N | If N, disable the zero offset button and value offset input in parameter properties. | Y | No |
| Auto save DTV changes | Y / N | Auto-save modified data versions when necessary without prompting; saved to next incremented version. | N | No |
| Enable Enhanced RDA DTV unlocking | Y / N | Allow RDA settings on Enhanced RDA2 DTVs to be disabled. | N | No |
| Disable DTV backup | Y / N | If Y, DTV backup files are not created/updated after each edit (performance improvement). | N | Restart |
| Default Virtual Parameter format to XML | Y / N | If N, revert Virtual Parameter file save format to historical binary VPM format. | Y | Restart |
| Disable Search for DTV on opening PGV | Y / N | If Y, disable multi-application search after PGV change (may improve performance). | N | No |
| Use Encrypted Parameter Unlock List Files | Y / N | If Y, Parameter Unlock List files are read/written in an encrypted format. | N | No |
#### Backups and file locations
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Save Document Backups | Y / N | Automatically save backup copies of documents. | N | No |
| Directory for backup files | Path | Override default location for backup files. Leave blank to use System Monitor's default location. | (blank) | No |
| Directory for configuration and macro files | Path | Location of logging configuration files and macros. Leave blank to use System Monitor's default location. | (blank) | No |
| Directory for exporting logging files | Path | Location for exported logging configuration files. Leave blank to use System Monitor's default location. | (blank) | No |
| Ident translation file | Path | Pathname of the file used to translate parameter identifiers when they change between versions. | (blank) | Restart |
| File for sensor calibration | Path (.prm) | Pathname of the .prm sensor calibration file; System Monitor requires the correct path to locate it. Leave blank to use System Monitor's default location. | (blank) | No |
| File for unit IP addresses | Path | Pathname of the Unit Definition file used to resolve unit IP addresses. Leave blank to use System Monitor's default location. | (blank) | No |
#### Logging configuration
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Logging Config ID Seed | 0 – 3 | Seed applied to Logging Config ID to help ensure unique config IDs between units. | 0 | No |
| Limit Logging To MAX_REFRESH | Y / N | If Y, enforce maximum refresh rates for parameter logging; if N, allow rates above max with warning. | N | No |
| Session Row Logging Interval (ms) | Numeric (ms) | Interval for session row logging in milliseconds. | 1000 | No |
| Directory for log files | Path | Location for System Monitor's own log files. Leave blank to use System Monitor's default location. | (blank) | Reconnect |
| Enable log file per project | Y / N | Create log files unique to each project name to aid identification when switching projects. | N | Restart |
| Automatic IP Message Logging | Y / N | If Y, a new message log is started when the project is opened or unit selection changes; if N, logging is controlled by the Record button. | N | Reconnect |
| Message log level (for debugging) | Levels / Not Logging | Enable logging of System Monitor messages for debugging. | Not Logging | Reconnect |
| Message log file size (MB) | Numeric (MB) | Sets the size limit for the message log. | (blank) | Reconnect |
| Export Extended MESL Config Binary | Y / N | Enable MCB Writer to export a binary MCB containing logging/telemetry description and IDs. | N | No |
| Log Single Messages | Y / N | If Y, log single messages from Active-X or GUI to individual log files. | N | No |
#### Sensors
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Enable New Sensor Subset Upload | Y / N | Enable upload of new sensor subsets. | N | No |
| Prompt New Sensor Subset Upload | Y / N | Enable a prompt when uploading new sensor subsets. | N | No |
| Zero Offset Sampling Time (ms) | Numeric (ms) | Duration for sampling to compute an average zero offset value. | 5000 | No |
#### Comms and ECU link
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Timeout before link lost (ms) | Numeric (ms) | Time System Monitor will attempt to send a message before treating the link as lost. | 2000 | No |
| Read Ram View Timeout | Numeric (ms) | Timeout for Read RAM view operations. | 100 | No |
| Use extended read RAM messages | Y / N | Use extended read RAMs if the unit supports them (faster large reads). | Y | Reconnect |
| Use extended write RAM messages | Y / N | Use extended write RAMs if the unit supports them (faster large writes). | N | No |
| Enable FIA lock checking | Y / N | Check for FIA-locked ECUs before reprogramming and prevent programming of not-permitted versions. | N | No |
| Default message timeout (ms) | Numeric (ms) | Timeout for messages sent to the unit. | 200 | No |
| Disable Encrypted Comms | Y / N | If Y, disables encrypted comms (enables network logging but disables some programming features). | N | Reconnect |
| Preferred port for unit link | Port (hex/dec) | Default starting port for unit connection; if unavailable, the port is incremented and retried. | 0xC000 (49152) | No |
| Increase ECU Bar display contrast | Y / N | Change ECU Bar text colours for greater contrast in bright conditions. | N | Reconnect |
#### ECU programming and control
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Enforce Prime Parameter requirements | Y / N | Allow Prime Parameters to be toggled per Application via the Parameter Explorer context menu. | Y | No |
| Enable Matlab Export after each parameter tune | Y / N | Control writing of Tune Log entries and Matlab export after parameter tunes. | N | No |
| Enable Matlab Export after DataWizard Merge | Y / N | Control Matlab/Tune Log export after DataWizard merges. | N | No |
| ECU Read Only mode | Y / N | When Y, user cannot modify values on the ECU. | N | No |
| Prompt for confirmation on Remote Reset | Y / N | If N, remote reset executes without a confirmation prompt. | N | No |
| Enable Multi Document Options in Open Dialog | Y / N | When N, open dialog does not offer multi-document options for CAN and remote logging configs. | Y | No |
| Minimum default time before leave boot (ms) | Numeric (ms) | Minimum time before sending the leave boot message at end of programming. | 0 | No |
| Enable Enhanced Slow Row | Y / N | Enables the enhanced slow row acquisition mechanism. | Y | Restart |
#### Miscellaneous and integration
| Setting Name | Options Available | Description of Setting | Default | Restart/Reconnect required |
|---|---:|---|---|---|
| Enable export of associated documents with project export | Y / N | Include Program Version documents when exporting a project to reduce manual inclusion. | N | No |
| Enable Unit.Def configuration | Y / N | Replace Customer Base project management with Unit.Def file management. | N | Restart |
| Suppress Licence Expiry Warnings | Y / N | If Y, System Monitor does not show warnings when a licence is due to expire. | N | No |
| Enable Remote Configuration Upload | Y / N | Allow remote configuration to be uploaded from the ECU. | Y | No |
| Enable FFC creation for PGV and Logging Configuration | Y / N | Enable creation of an FFC file alongside PGV and Logging Configuration files. | N | No |
| Suppress 'Not live-tuneable' warning during import | Y / N | If Y, suppresses the warning normally shown when importing parameters that are not live-tuneable. | N | No |
| Auto-increment filename for all numerically terminated files on save | Y / N | If Y, automatically increments a trailing number in the filename each time a file is saved. | N | No |
| Enable Logging of API Calls | Y / N | Enable logging of calls made through System Monitor's API. | N | No |
---
# Overview
System Monitor has various safeguards to ensure that only the correct data and programs are transferred to an ECU. This is done either by using the Customer Base, which links the ASAP project to the file directories used by System Monitor or Unit.DefManagement.
Each control system has associated ASAP and Hex files, which should be supplied by the ECU manufacturer. System Monitor generates Program and Data Version files from these ASAP and Hex files and only accepts ASAP files from the ASAP project specified in the Customer Base. The Program and Data version files are placed in the Customer Base directory.
A System Monitor Project links the Program and Data version files for an ECU with the Desktop that you use to configure the ECU. When Customer Bases are used, each project is associated with a Multi-Application Base that contains one or more Applications. The Project files are placed in the Multi-Application Base Directory. When Unit.Def support is used, the project file location is used as the base directory.

## Creating a Project
A project requires a Program Version for each Customer Base in the Multi-Application Base therefore Program Versions must be created before you can Create a Project.
The ECU manufacturer may supply Program Versions as well as the ECU files, in which case it will not be necessary to create the Program Versions.
---
# Customer Base
## Customer Base
A Customer Base links an ASAP project to the file directories used by System Monitor. It ensures that only files associated with the specified ECU are used.
- Each Customer Base defines an Application within a Project.
- Customer Bases are associated with Projects via a Multi-Application Base.
- Editable via the Select Active Multi-Application Base dialog.
### Adding or Editing a Customer Base
Use the Enter Customer Base Details dialog:
- **Customer Base**: Unique name.
- **ASAP Project**: Must match the project name embedded in the ASAP file.
- **Base Directory**: Must be a sub-directory of the Multi-Application Base directory.
Overwriting or removing a Customer Base that is part of a Multi-Application Base will break access to its data.
## Multi-Application Base
Controls access to files and prevents incorrect ECU programming.
- Contains one or more Customer Bases.
- Typically set up by the control system supplier.
- Can be added or removed by Free Users.
### Selecting a Multi-Application Base
1. Go to `File > Select Base`.
2. Choose from available bases in the dialog.
### Prime Parameter Override File (.ppo)
Used to configure prime parameters in logging setups. Format:
`App id, parameter identifier, minimum frequency1,vCar,200 1,tTotalShiftTime,500`
- No header line.
- Minimum frequency of 0 removes the prime property.
- Requires "Enforce Prime Parameter Requirements" to be enabled.
## Free User Status
A Free User can create and remove Multi-Application Bases.
If you have Free User status, you will see a Multi-Application Base with the name ‘Free User’ in the Select Active Multi-Application Base dialog box and the Add and Remove buttons in the Multi-Application Bases panel are active.
Free Users can select a Multi-Application Base in the usual way. However, if you select ‘Free User’ as your active Multi-Application Base, you will be able to load any ASAP file without restriction. You will also have access to any directories, under the Free User Base Directory, to store any System Monitor files that you create.
---
# Unit.Def Files
Unit.Def files are XML-based configuration files that define project options. They replace the legacy Multi-Application and Customer Base structure. There can be one Unit.Def file per folder and it is applied toprojects opened in that folder. The absence of a Unit.Def file will result in System Monitor resortingto default options for any projects located in the folder.
## Configuration
- One Unit.Def file per folder.
- Applied to all projects in that folder.
- Managed via `File > Manage Unit.Def Files…` (only when no project is loaded).
## Applications
Applications can be added manually or auto-configured by scanning PGV files in subfolders.
- Each application requires an ASAP definition name and default folder.
- Applications can be enabled/disabled or deleted.
- One application can be set as the master.
## Options
- Define default locations for project files.
- Override comms path settings.
- Specify a Prime Parameter Override (.ppo) file.
## Saving
Changes are saved when selecting a new Unit.Def file or exiting the dialog.
## Opening Projects
Three methods:
1. `File > Open… Ctrl+O`: Opens from the most recent Unit.Def folder.
2. `File > Open… >`: Browse any folder.
3. Recent Projects list: Quick access to last 10 projects.
System Monitor looks for a matching Unit.Def file in the selected folder.
---
# Creating Versions
Each ECU contains one or more controllers, which require programming before use. The ECU manufacturer usually programs the controllers before despatch, however System Monitor can reprogram the ECU. SystemMonitor also uses the program to recognize the configuration of the ECU.
A controller used in this type of application is known as an embedded control system. A description of the embedded control system is supplied in the form of an ASAP file and a Hex File. The ASAP file contains the descriptions of the embedded control system and the Hex file contains the program code and program data.
## File Types
- **Program Version (.pgv)**: Contains ASAP content, program code, and configuration.
- **Data Version (.dtv)**: Contains editable parameters and memory layout.
## Creating Program Versions
1. Start System Monitor.
2. `File > New > Program Version`.
3. Select required files:
- ASAP2 (required)
- Hex (required)
- Controllers (required)
- Optional: Errors, Events, Sensors, etc.
4. Enter comments and notes.
5. Click OK to generate `.pgv` and `.dtv`.

## Command Line Creation
Syntax:
```
SMv7U /newpgv /asap2 "pathasap2"/hex "pathhex " /controller"pathcontroller" /error"patherror" /event"pathevent" /sensor"pathsensor" /endis"pathendis" /injector"pathinjector" /prm"pathprm" [/customer basename] [/location folder] [/encrypt encryptionmode]
```
- **pathxxxx**: The full path name of the following files:
- **pathasap2**: Asap2 File. Must come from the ASAP project specified in the Customer Base.
- **pathhex**: Hex File. Must match the ASAP2 file and be suitable for the ECU.
- **pathcontroller**: Controllers File. Must be suitable for the ECU.
- **patherror**: Errors File. Required if you want to view Errors.
- **pathevent**: Events File. Required if you want to view Events.
- **pathsensor**: Sensors File. Required if a Sensor Injector file is loaded (See Sensors).
- **pathendis**: Sensor Enable/Disable File. Required if you want to Enable and Disable sensors.
- **pathinjector**: Sensor Injector File. Required if the Sensors file includes injectors.
- **[/customer basename]**: Optional. The name of the Customer Base in which the Program Version is to be stored.
- **[/location folder]**: Optional. The location Base in which the Program Version is to be stored.
- **[/encrypt encryptionmode]**: Optional. The encryption mode should be either:
- `0`: No encryption
- `1`: Encrypt PGV files on creation. If this parameter is not specified, no encryption is used.
### Return Codes
`0` success, `1` licence error, `2` invalid command, `3` command failed.
---
# File Types
System Monitor uses several different files in the following categories:
- [ECU Files](#ecu-files) - Embedded software files distributed by the TAG customer support team or by the ECU manufacturer. Not part of System Monitor.
- [Program and Data Version Files](#program-and-data-version-files) - The System Monitor working files. Generated by System Monitor from the ECU files.
- [Project Files](./file-operations.md/#exporting-and-importing-files) - Files generated by System Monitor to store its own configurations.
System Monitor stores project files in a structured directory layout under the Multi-Application Base.
## Directory Layout
```
\MultiAppName\
├── CustBaseName\
│ └── version\
│ ├── version.pgv
│ └── version000.dtv
├── Desktops\
│ └── ProjectName.dtp
├── LogCfgs\
├── Sessions\
├── Virtuals\
├── Work\
├── SenSets\
├── HistReps\
└── ProjectName.prj
```
### Description
- **MultiAppName**: Top-level directory for the Multi-Application Base
- **CustBaseName**: Sub-directory for each Application
- **version**: Contains Program and Data Version files
- **Desktops**: Stores Desktop files
- **LogCfgs**: Default location for logging configurations
- **Sessions**: Stores session logs from Live Logging
- **Virtuals**: Stores virtual parameter files
- **Work**: Stores event logs
- **SenSets**: Stores sensor and actuator configurations
- **HistReps**: Stores history report files
- **ProjectName.prj**: Main project file
Each new project creates its own `.prj` file and associated subdirectories.
## Program and Data Version Files
The Program and Base Data Version files are generated by System Monitor when a New Program Version is created.
### Program Version File (.pgv)
Encapsulates all program-related artifacts for a program version.
- Typical contents (generated by System Monitor):
- Full content of the ASAP2 (.a2l) file.
- Program code for each ECU controller (from the HEX file).
- The content of any additional files selected during creation.
- Unique program version stamp (version).
- Base directory and program version directory and filename.
- ECU type and names of the original .hex and .a2l files.
- Free-form comment/notes.
### Base Data Version File (.dtv)
Contains the base set of calibration/data values and related metadata.
- Typical contents:
- Data for each controller forming the base parameter set (from HEX).
- Data-area memory layout (from ASAP2).
- Short and long comments/notes and the creating user name.
- Unique stamp linking to the associated .pgv (program version).
- Base directory, program version directory and filename.
- Unique data version stamp and the default filename (version000.dtv).
## ECU Files
ECU files are the embedded software files for the ECU, distributed by the customer support team or by the ECU manufacturer. Not part of System Monitor.
- Required by System Monitor:
- ASAP2 (.a2l) — ASAP2 project/description file required for mapping parameters and memory layout.
- HEX (.hex) — compiled program + data; provides program code and controller data.
- Controllers (.ini) — controller list and per-controller properties/IDs.
- Optional (may be supplied by customer support or manufacturer):
- Errors (.ini), Events (.ini), Adjustment Parameters (.ini)
- Sensors (.ini), Sensor Injector (.ini)
- Sensor Enable/Disable (.ini)
- Sensor PRM (.prm) — paths/filenames for ASCII calibration data
- Live Auto Tune (.ini) — tuning-related configuration (TBC)
### File Content
- ASAP2 (.a2l)
- Project name/security reference and ECU type.
- Version string used for naming/version directory.
- Definitions for measurement and editable parameters, groups, conversion formulas, axes, and memory location information for controllers and parameters.
- HEX (.hex)
- Program code for each ECU controller.
- Controller configuration including revision/date/data-version stamps and data area sizes/locations.
- Base data values used as the initial calibration set.
- Controllers (.ini)
- Defines the list of controllers (including possible external controllers), their names, IDs, ident numbers (for cross-reference to ASAP2), and controller properties.
- Sensors and Related Files
- Sensors (.ini) — lists available sensor types and selected sensors; defines sensor data memory for controllers.
- Sensor Enable/Disable (.ini) — sensors that can be toggled on/off by ECU.
- Sensor PRM (.prm) — links to ASCII calibration files for sensors.
- Live Auto Tune (.ini) — placeholder for live autotune configuration details.
---
# Application Management
## Applications
Applications represent functional areas of the ECU system, such as:
- **BIOS** – core control system
- **Chassis** – vehicle chassis control
- **Engine** – engine control
Each application is linked to a Customer Base and can be set as Active or Read Only.
## Active Applications
A Project contains one or more Applications. System Monitor controls which applications are affected by various operations, especially those involved in Developing Data Versions. The applications that are affected are called the Active Applications.
The Active Applications are shown bold in the Parameter Explorer and the ECU Bar.
### Managing Active Status
- Use `File > Active Application` or right-click in the Parameter Explorer.
- Shortcut: `ALT+A`
- In Parameter Explorer or ECU Bar: toggles active status.
- In Main Window: cycles through applications if only one is active.
!!! note
Changes can only be made when the ECU is Off-Line and Live Updates are disabled.
## Read Only Applications
Applications can be set to Read Only via the File Menu or Context Menu. An application that is both Active and Read Only cannot be edited but is included in operations like reprogramming.
## Application Properties
Accessible via `File > Properties > Application`.
Tabs include:
- **Program Version** – shows file details and source files.
- **Data Version** – shows current data file and metadata.
- **Memory Layout** – displays memory usage.
- **Unlock List Management** – controls access to parameters.
## Unlock List Management
The Unlock List Management tab allows teams to Manage the Unlock Lists associated with the Application. Unlock lists are managed on a per Application basis, if the user is authorised for full access to that application.
- Unlock lists are managed per team.
- Parameters can be added or removed via the Select Parameters dialog.
- Once locked, an application cannot be unlocked. Backups should be created beforehand.
!!! note
Before locking an application, you should ensure that a backup of the unlocked application is created, as you cannot unlock an application once it is locked. Due to the unlocked state of this application, you should store it in a secure location.
---
# Data Version Development
When a project is Created a Base Data Version is allocated to each Application in the project. The Base Data Version contains a full set of Editable Parameters with values that should enable the vehicle to operate, if not at its optimum.
As the ECU is tuned to optimize the performance of the vehicle, the values of the Editable Parameters are changed. The changes are stored by System Monitor in the Edit Buffer. If the ECU is On-Line, the contents of the Edit Buffer can be sent to the ECU either immediately (using Live Tune) or on demand.
**Features**
- The Data Version in the ECU can be uploaded to the Edit Buffer.
- Only Active Applications can be tuned. Ensure that the applications that you want to tune are set as active and are not read only.
- The contents of the Edit Buffer can be saved at any time, to create a new Data Version File. If the contents of the Edit Buffer are different from the currently loaded Data Version, you will be prompted to save the new Data Version when the ECU is taken Off-Line or the project is closed. Data Versions are saved in the Customer Base directory of the Active Application.
- A Backup of the Edit buffer is stored as: \MultiAppName\CustBaseName\version\version000xxx.dvb
where: xxx is the user name of the person who is currently logged on. See Project Files for a description of the file structure. The location can be overridden by an entry in Tools > Advanced Settings.
## Using Data Version Files
To load a different Data Version:
1. Select the Active Application.
2. `File > Open > Data Version (.dtv)`
3. Browse and select the file.
Changes to the Edit Buffer prompt a save when the ECU is taken Off-Line or the project is closed.
## Saving Data Versions
- File name format: `versionnnn.dtv`
- `nnn` is a three-digit hex number incremented with each new version.
- Comments and notes can be edited before saving.
- Old versions are retained unless overwritten manually.
!!! note
- File names and location may be changed but the location can only be within the Multi-Application Base directory.
- Comment and Notes in the Data Version panel can be edited before the file is saved.
- Old Data Version files are not overwritten except to change the Comment and Notes.
## Export to MATLAB
The MATLAB export creates one or more MATLAB script files (*.m) from the Data Version currently in the Edit Buffer. These files can be used for analysis in MATLAB or produced by MATLAB for re-import into System Monitor (directly or via Hex files).
Export options:
- Definition and Data
Includes Property settings and the value(s) for each Editable Parameter.
- Data only
Includes only the value(s) for each Editable Parameter.
How to export
1. Select the Active Application.
2. Choose: Tools > Export to MATLAB > Definition and Data or Data only.
3. In the Save As dialog, confirm the Save as type is "MATLAB Script Files (*.m)". A separate .m file is created for each Active Application.
4. Choose a folder and file name, then save.
- Default file name: progversiondataversion.m
- progversion: Program Version number used by the Application
- dataversion: Data Version number used by the Application (including its sequential number)
- The Save As dialog opens at the default path (the location of the currently loaded Data Version). You may store the file anywhere you have write access.
!!! tip
- Use "Definition and Data" when you need parameter metadata (units, conversions, properties).
- Use "Data only" for a compact export of values for numerical analysis or scripting.
- Confirm Active Applications are the ones you intend to export; only Active Applications produce files.
- Ensure you have write permissions for the chosen export folder.
## Importing Hex Files
System Monitor creates Data Versions from the information in Hex files (see Program and Data versions and ECU Files). This is normally done as part of the process of Creating a Program Version. However, it is possible to import a Hex file into an existing Project to create a new Data Version. To do this select: **File > Import Hex File** to browse for a Hex file.
If the Hex file is compatible with the project, a new Data Version is created. This facility can be used to incorporate development data from other applications such as MATLAB into System Monitor.
---
# Data Wizard
Data Wizard compares the contents of the Edit Buffer with one or more previously created Data Versions, known as Candidate Data Versions. Using the Merge facility parameters in the current Data Version can be overwritten with those in the Candidate Data Versions.
**Features**
- Compare/Merge Tool
- Candidate Version Window
- Report View Window
### Compare/Merge Tool
The Compare/Merge Tool compares Parameters from one or two Candidate Data Versions with the Merge Buffer, and allows values from a Candidate Version to be Merged into the Merge Buffer and then committed to the Edit Buffer.
#### Merge Values
1. On the top-row drop-down list, select the Applications base to compare.
2. On the Dtv 1 row, browse for a Data Version or select one from the recently compared drop-down list.
Note: Dtv1 and Dtv2 Data Versions must share the same Program Version.
3. On the Dtv 2 row, browse for or select a Data Version.
4. Select a display criterion for parameter values from the drop-down list (for example, Value, Delta Value).
5. The main window displays the differences between the Data Versions selected in Dtv 1 and Dtv 2 and the Merge Buffer.
6. To update a parameter value in the Merge Buffer with a value from one of the other Data Versions, click the `>` or `<` column in the appropriate cell. Click the same cell again to undo the change.
!!! note
Merge Buffer values can be edited directly in the Memory column. If the Merge Buffer differs from the Edit Buffer, an asterisk (*) is displayed in the Memory column header.
#### Commit Changed Values
1. To commit all changes in the Merge Buffer to the Edit Buffer, click Commit.
2. The display is updated to show only those parameters that are still different.
### Map Compare Window
The Map Compare Window displays values for Dtv 1, theCurrent Data Version and Dtv 2. The window mimics the Map Window for theParameter, displaying the relevant number of Breakpoints on all axes.
To open a Map Compare Window, double-click a 1-Axisor 2-Axis Parameter in the Compare/Merge Tool Window.
### Minimum/Maximum Data Versions
If a minimum and/of maximum Data Version file is available in the Program Version folder, it is accessed by System Monitor and used in the Compare Merge Tool to indicated if minimum or maximum values have been exceeded.
Minimum and maximum Data Version files (.dtv) can be used as Dtv1 and Dtv2 Data Versions in the Compare/Merge Tool.
To create a Minimum or Maximum Data Version:
- Edit a Data Version and save it using the filenames
- MIN.dtv for the minimum Data Version
- Max.dtv for the maximum Data Version
where pppp is the Program Version number.
!!! note
Save the min and max Data Versions in the same folder as the Program Version.
## Candidate Data Versions
The Candidate Data Version is a previously created Data Version that you want to compare with the contents of the Edit Buffer.
Features:
- Individual Candidate Data Version Windows can be printed but are not included if you print a Page.
- Candidate Data Version Windows are not stored as part of the Desktop and are not reloaded if a Project is closed and re-opened.
- More than one Candidate Data Version Window may be opened at once. Merge operations apply to all the open Candidate Data Version Windows.
- The display of Names and Descriptions reflects the setting in the Parameter Explorer.
To open a Candidate Data Version Window:
1. Select: Data Wizard > Open Data Version and select a file *or*
2. Select a Data Version file from the Recent Files list on the Data Wizard Menu. *or*
3. Select File > Open to select the Data Version file. DO NOT open the file. Click Data Wizard.
The Candidate Data Version Window appears on all pages. The full path name of the Data Version file is displayed on the Title bar.
## Report View
The Report View Window shows the parameters in the Edit Buffer. These are compared to the same parameters in the current Data Version using the Different Value Mask and shows shows all changes made to application since data version was opened / last saved.
The Report Window appears on all pages. The full path name of the Data Version file is displayed on the Title bar. To avoid confusion, it is advisable to use Data Wizard on a blank Page.
To open a Report View Window:
1. Select: Data Wizard > Report View. A Window is opened for each Active Application. *or*
2. Select an Application in the Parameter Explorer, access the Context menu and select: Report View.
!!! note
Report View Windows are not updated automatically. If you change any parameters in the Edit Buffer and want to force an update, select: Data Wizard > Compare / Compare All.
## Parameter Masking
Filters parameters by type of difference:
- Absent
- Different Definition
- Different Size
- Different Data Type
- Different Conversion
- Different Units
- Different Value
- Equal
## Merge Operations
Merging attempts to overwrite parameters in the Edit Buffer, with the definition of the same parameter in a Candidate Data Version. If a parameter has a Different Definition, the parameter is not merged
1. Select: `Data Wizard > Merge` or `Merge All`.
- **Merge** - Merges the current Data Version with the Candidate Data Version(s). The Selected Parameters and the Parameter Mask are not changed. Only the parameters displayed in the open Candidate Data Version Window(s) are merged.
- **Merge All** - Merges the current Data Version with the Candidate Data Version(s). Before the merge operation is carried out, the Selected Parameters and the Parameter Mask are reset to their default values. All parameters are merged whether or not they are displayed in the open Candidate Data Version Window(s).
2. If the difference between the parameters is their value, conversion, or units, the raw bit value (the value before Conversion) is used for the merge.
3. If the difference between the parameters is their data type, the scaled value (the value after Conversion) is used for the merge.
4. If the differences cannot be resolved automatically, the **Resolve Parameter Merge** dialog box opens.
5. Check marks show which differences have been found for the parameter named at the top of the dialog box.
6. Select a method to merge the value by selecting from the available radio buttons. See dialog box.
7. If more than one Candidate Data Version is open, and the same parameter appears in more than one of them, the **Resolve Merge Conflict** dialog box opens.
8. The list shows the full path names of the candidate Data Version files that contain the parameter named at the top of the dialog box.
9. Select the file from which you want to merge the parameter and click OK.
10. If you select Cancel, the parameter is not merged and remains unchanged.
## Viewing Parameters
Data Wizard allows temporary Windows to be opened to display the values of selected Parameters.
## Window Menu
The Data Wizard Window Menu commands control the appearance of a Report View or a Candidate Data Version Window.
---
# ECU Connection
The Connections tab is used to view and modify the way System Monitor is connected to the ECU. To open the Connections tab select: **File > Properties > Connections** or use the ECU Menu.
## Connection Methods
- **IP (Ethernet)** – TCP/IP connection
- **HDLC (CA-Card or PCMCIA)** – Serial connection
- **CAN (VECTOR card)** – Uses VECTOR XL Driver Library
### IP via Ethernet
1. Select `IP via Ethernet` in the Connections dialog.
2. Choose a Unit Definition for the main unit.
3. Choose a Unit Definition for the spare unit.
4. Edit Unit Definitions if required.
5. Select an ATLAS data server.
6. Click `Next` to continue to Desktop setup.
## Unit Definition
Defines ECU identity and IP configuration.

### Adding a Unit Definition
1. Click `Add`.
2. Enter a name.
3. Select ECU type.
4. Enter IP address(es).
5. Click `OK`.
### Editing or Removing
- Select the Unit Definition from the list.
- Modify name, type, or IP address.
- Click `Remove` to delete.
## Spare Unit
Typically, development and Tuning is done using one unit and it may be necessary to transfer the settings (Program and Data versions) to another unit. If the ECUs communicate over an Ethernet network, each unit has an unique IP Address so that the unit(s) designated as the spare will have different address(es) from the unit(s) designated as main.
The Unit Definition for the Spare unit is defined for the Project in the New Project - Connections dialog box or the Project Properties dialog box, Connections tab.
### Programming the Spare Unit
1. `Tools > Program Spare Unit`
2. Select applications to program.
3. Enable merged programming sequences if needed.
4. Select components to download.
5. Click `OK`.
### Checking Unit Status
- `Tools > Unit Status` opens the Unit Status dialog.
- Allows upload/download of files and inspection of current ECU contents.
---
# File Operations
System Monitor uses various file types for ECU configuration, logging, and tuning.
## Create a Project
1. Select `File > New`. The File New dialog box opens.
2. In the Document list, select **Project** and click **OK**. The Project dialog box opens.
4. Enter a filename in the **Filename** text box, or browse for a path or an existing project filename (browsing is limited to the Multi‑Application Base directory).
5. Enter a **Comment** and **Notes**, if required.
6. Click **Next** to continue. The Connection dialog box opens — see *New Project - Connections* for further instructions.
## Opening Files
Use `File > Open` to access:
- Data Version (.dtv)
- Program Version (.pgv)
- Desktop (.dtp)
- Logging Configurations
- Sensor Sets
- History Reports
- Virtual Parameters
- CAN Config
- Project (.prj)
If no project is open, only `.prj` files can be selected.
## Saving Files
### Save
- Saves changes under the original name.
- Overwrites the existing file without warning.
### Save As
- Saves under a new name.
- Allows editing of comments and notes.
- For Data Versions, prompts for a new name unless only comments were changed.
### Save Copy As
- Saves a copy under a new name.
- Original file remains unchanged.
### Save All
- Saves all modified files under their original names.
### Save All As
- Saves the entire project and all associated files under a new name.
## File Type Selection
Appears when using New, Open, Save, or Save As commands. Lists available file types for the selected operation.
## Exporting and importing files
Use Export and Import to copy Project, Program and Data Version files (.pgv, .dtv, etc.) between Multi‑Application Bases. The export format is .smx, which can only be read by System Monitor’s Import facility.
### Exporting files
1. Open: File → Export → "Export Files from Customer Base" dialog.
2. The **Active Multi‑Application Base** panel shows read‑only info about the current Base.
3. In **Export to file**, enter or browse for the destination path and filename (use the .smx extension).
4. The **Files to export** list shows files that will be included.
5. Click **Add** to open a File Open dialog and select files from the Multi‑Application Base. If you add a project .pgv file, all files associated with that project are included.
6. To remove an item, select it and click **Remove**.
7. Click **Export** to create the .smx file and close the dialog.
Note: Exported .smx files can only be read by System Monitor’s Import command.
### Export Project
- Creates a snapshot of the current project containing all files in the project.
- The file is named after the project with the .smx extension and is placed in the project’s directory.
- No dialog is shown and there are no options.
### Importing files
1. Open: File → Import → "Import Files into Customer Base" dialog.
2. The **Active Multi‑Application Base** panel shows read‑only info about the current Base.
3. In **Import from file**, enter or browse to the .smx file to import.
4. The **Files to import** list displays the contents of the .smx file. Select files by checking their boxes, or highlight files and use **Include** / **Exclude**.
5. Click **Import** to extract the selected Program and Data Version files into the current Base directory and close the dialog.
6. Confirm or resolve any overwrite prompts as required by the application.
---
# Overview
The System Monitor is a data display tool designed to provide feedback during tuning by visualising Measurement Parameters. While it offers basic display capabilities, more advanced analysis is available through the [ATLAS visualiser](../../../../analyse/viewer/index.md).
System Monitor presents data using various display windows, each tailored to different visualisation needs. These windows are configured to show live data from Measurement Parameters, and can be customised extensively via the Window Properties dialog.
## Display Types
System Monitor supports multiple display formats to suit different data visualisation requirements. Each format uses a dedicated window type:
### [Numeric](numeric.md)
Displays one or more Measurement Parameters in rows with descriptive text.
### [Big Number](numeric.md/#big-number-display)
A variant of the Numeric display using a large font. Created automatically when a single parameter is selected via Parameter Explorer.
### [Bar Graph](bar.md)
Displays parameters as vertical or horizontal bars. Bar height and colour reflect parameter values and warning limits.
### Dial Gauge
Displays a single parameter on a dial-style gauge.
### [Oscilloscope](oscilloscope.md)
Plots parameters against time, supporting multiple trace types (Linear, Digital, Logical).
### [Grid](grid.md)
A spreadsheet-style layout allowing placement of text and parameter attributes in cells. Supports editable parameters and custom formatting.
### [Signal Sampling](signal.md)
Provides functionality to sample or zero one or more input signal parameters.
## Adding Display Windows
Display windows can be added to a System Monitor page via the menu: `Desktop > Window > [Display Type]`
---
# Numeric
The Numeric Display shows one or more Measurement Parameters in a tabular format. Each parameter is displayed in a row with descriptive text.

## Features
- Each row includes:
- **Name / Description**: Configurable via the Parameters Sheet in the Window Properties dialog.
- **Value**: Display format set in the Parameters Sheet or System Menu.
- **Units**: Engineering units symbol or text.
- **Status Icon**: Indicates value change or error condition.
- Column widths can be adjusted.
- Parameters can be sorted.
- If a parameter is not included in the Live Logging Configuration, its value is replaced by a dash.
## Big Number Display
A Big Number Display is a specialised Numeric Display created when a single Measurement Parameter is selected via Parameter Explorer.

### Differences from Numeric Display
- Uses the default large font.
- Name column is hidden.
- Parameter Name/Description shown in the title bar.
- Column headings are hidden.
---
# Bar
The Bar Graph Display visualises one or more Measurement Parameters as bars. Each bar's height and colour reflect the parameter's value and status.

## Features
- **Bar Height**: Proportional to parameter value.
- **Bar Colour**:
- **Normal**: Between warning limits (default grey).
- **Low**: Below low warning limit (default blue).
- **High**: Above high warning limit (default red).
- **Orientation**: Bars are vertical by default; can be changed to horizontal via System Menu.
- **Max/Min Values**: Shown beside each bar; editable via Display Limits dialog.
- **Warning Limits**: Displayed and colour-coded.
- **Name/Description**: Shown below each bar.
- **Value**: Engineering value shown below name/description; matches bar colour.
If a parameter is not in the Live Logging Configuration, “not logged” is displayed.
## Selecting Parameters
- **Single**: Click bar or use cursor keys.
- **Multiple**:
- Mouse: CTRL + click.
- Keyboard: CTRL + cursor keys + SPACE.
- **All**: Use "Select All" from the Bar Graph Context Menu.
## Display Limits
To change the display range for a parameter:
1. Open the Bar Graph Context Menu.
2. Select **Display Limits**.
3. Edit Low and High values.
---
# Error
The Error Display shows diagnostic error flags from the ECU. Each error is represented by a special Measurement Parameter.

## Features
- Errors are defined by the Error File included in the Program Version.
- Errors are uploaded live from the ECU (must be Online).
- Errors are listed in order of occurrence.
- Duplicate errors are not shown multiple times.
- Errors can be:
- **Current**: Actively occurring.
- **Logged**: Stored in the ECU from past occurrences.
- Logged errors persist until deleted.
## Creating an Error Window
Select: `Desktop > Window > Error`
Each error appears as a row with:
- **Status Icon**:
- Current error
- Logged error
- **Name**: From Error File.
- **Description**: Cause or details.
- **Status**: Current or Logged.
## Managing Errors
- **Acknowledge**: `ECU > Acknowledge Errors`
- Changes colour from Unacknowledged to Foreground.
- **Delete**: `ECU > Delete Errors`
- Removes logged errors from ECU and display.
- **Masking**:
- Use the Mask tab in Window Properties.
- Mask entire groups or individual errors.

## Display Options
- Errors appear on every page by default.
- Window auto-restores if minimised during error occurrence.
- Column widths are adjustable.
- Appearance settings available in Display tab and System Menu.
---
# Event
Events report status changes in the control system and include a timestamp. They are defined by the Event File in the Program Version.

## Features
- Events are displayed in order of receipt (most recent at bottom).
- Maximum of 2000 events per window; older entries are deleted.
- Events are automatically logged to: \work\Ev_.log
- Events can be saved manually via `Save As`.
## Creating an Event Window
Select: `Desktop > Window > Event`
Each event appears as a row with:
- **Priority Icon**: High, Medium, or Low.
- **Date**: When the event occurred.
- **Time**: Timestamp.
- **Event Name**: From Event File.
- **Description**: Diagnostic info (HEX or converted text).
## Display Options
- Events appear on every page by default.
- Column widths are adjustable.
- Appearance settings available via Display tab and System Menu.
## System Menu – Events
- **Clear All Event Windows**: Removes all listed events.
- **Save As**: Save events to a file.
## Event Masking
- Use the Mask tab in Window Properties.
- Mask by:
- **Group**: Entire application group.
- **Individual Events**
- **Priority Level**: Low, Medium, High, All

---
# Grid
The Grid Display is a flexible, spreadsheet-style layout that allows text and attributes of Measurement or Scalar Parameters to be placed in cells. It is commonly used to create customised views for specific operations.

## Features
- Editable Parameters can be highlighted using a different background colour.
- Values not included in the Live Logging Configuration are shown as a dash.
- Appearance controls are available via the Window Properties dialog and System Menu.
- Grid Displays can replicate the look and function of custom pages from System Monitor Version 6.
## Edit Mode
Edit Mode allows modification of cell content and layout.
- Enabled by default for new Grid Windows.
- When enabled:
- Column headers are shown.
- Column widths can be changed.
- Grid Cell Context Menu is available.
- Text and cell properties can be edited.
To disable Edit Mode, clear the checkbox in the Numeric Grid tab of the Window Properties dialog.
## Creating a Grid Window
1. Select: `Desktop > Window > Grid`
2. Configure:
- **Rows and Columns**: Set initial size.
- **General Panel**:
- Edit Mode: Toggle cell editing.
- Gridlines: Show/hide gridlines.

Click **OK** to create the window. Cells must be configured individually.
## Selecting Cells
- **Single**: Click or use cursor keys.
- **Multiple**:
- Mouse: SHIFT or CTRL + click.
- Keyboard: SHIFT or CTRL + cursor keys + SPACE.
!!! note
Non-continuous blocks cannot be copied.
## Cell Properties
To edit a cell:
1. Ensure Edit Mode is enabled.
2. Click the cell.
3. Press ESC to highlight.
4. Right-click > **Properties**
### Contents Tab
- **Empty**: Clears cell.
- **Text**: Enter free text.
- **Parameter**:
- Select a parameter.
- Choose attribute to display (e.g. Engineering value).
- Optional bit masking for logical display.

### Formatting Tab
- **Justification**: Set text alignment.
- **Borders**: Add thick borders.
- **Colours**:
- Use default or custom background colour.

## Insert/Delete Rows or Columns
- Use Grid Cell Context Menu:
- **Insert**: Specify number and placement.
- **Delete**: Remove selected rows/columns or cell contents.
---
# Oscilloscope
The Oscilloscope Display plots one or more Measurement Parameters against time. It consists of a Plot Area and a Parameter Info Box.

## Features
- **Trace Types**:
- **Linear**: Straight lines between values.
- **Digital**: Horizontal and vertical steps.
- **Logical**: TRUE (1.00) or FALSE (0.00); shown below the timebase.
- **Y-Axis**:
- Labelled Y-axis for selected parameters.
- Option to show Y-axis for all parameters.
- No Y-axis for Logical traces.
- **Timebase Duration**: Configurable in Extras tab.
- **Update Rate**: Set in Display tab.
- **Grid Display**: Optional background grid.
- **Band Clearing**:
- **On**: Previous traces overwritten.
- **Off**: Plot area cleared after each sweep.

## Parameter Info Box
- Shows Name and Value of each parameter.
- Can be hidden via Extras tab.
- Text colour matches trace colour.
- Width adjustable; height fixed relative to Plot Area.
## Selecting Parameters
1. Focus on the display.
2. Go to Desktop > Window > Properties
3. Add parameters in the Parameters tab:
- **Single**: Click name or use cursor keys.
- **Multiple**:
- Mouse: SHIFT or CTRL + click.
- Keyboard: SHIFT or CTRL + cursor keys + SPACE.
- **All**: Use "Select All" from Context Menu.
## Trace Limits
To adjust Y-axis limits:
1. Right click in the Plot Area.
2. Select **Trace Limits**.
3. Edit Low and High values.
!!! note
Trace Limits do not affect Logical traces.
---
# Signal Sampling
A signal sampling display can be added to a page by selecting **Desktop > Window > Signal Sampling**.

The signal sampling tool allows one or more input signal parameters to be sampled either independently or simultaneously. Parameters can be added to the display by dragging them into the display from the parameter explorer. They can be deleted either by selecting the parameter in the display and pressing the ‘delete’ key or via the parameter explorer.
Multiple signal sampling displays can be displayed on one page.
Each input signal parameter is displayed as a row with the following columns:
- **Name**: The name of the input signal parameter. This is set in the input signal configuration dialog.
- **Raw**: The raw (un-scaled) value of the input signal.
- **Units**: The units of the raw value of the input signal.
- **Reference**: The scaled value the signal should read when sampled. This value is user editable.
- **Scaled**: The current scaled value of the input signal including the offset. This is the value that will be logged.
- **Units**: The units of the scaled value of the input signal.
Input signal parameters can be sampled from the current value using one of the following options, all of which are available via both menus and keyboard shortcuts:
- **Selected Parameter Only**: This will simultaneously sample the selected parameter(s) only.
- **Sample Entire Display**: This will simultaneously sample all parameters within the currently selected input signal display.
- **Input Signal Sample Entire Page**: This is selected via the Logging menu. This will simultaneously sample all parameters on all signal sampling displays on the current page.
!!! note
There must be an active link to the unit for the sampling functionality to be selectable. If not, then the sampling menu options will be disabled.
If one or more parameters have been sampled, then the user will need to download the logging configuration to the unit so that the changes are applied. The ECU bar will indicate if the users’ current SM logging configuration file differs from the one on the unit.
---
# Alarms
The Alarm Display window shows active alarms triggered by defined conditions. It appears automatically when an alarm message is triggered, or can be opened manually via: Desktop > Window > Alarms
## Display Columns
Each alarm is shown in a row with:
- **Description**: The message text defined in the Actions tab of the Alarm Properties.
- **Time**: The time the trigger condition became TRUE.
## Features
- Rows are cleared when the trigger condition becomes FALSE.
- The window remains open even if all rows are cleared.
- Default location is at the top of the desktop, but it can be moved and resized.
- Column widths are adjustable.
- Alarm windows appear on every page by default.
## Alarm Setup
Alarms consist of a **Trigger** and a set of **Actions**. Actions are executed immediately when the trigger condition becomes TRUE.
### Creating Alarms
To open the Alarm Setup dialog: Desktop > Alarm Triggers
Each alarm is listed with its message text. Alarms are active when their checkbox is selected.
!!! note
Alarms operate immediately upon creation. The setup dialog does not need to be closed for alarms to function.
## Alarm Setup Controls
- **Add**: Creates a new alarm and opens the Alarm Properties dialog at the Trigger tab.
- **Properties**: Opens the Alarm Properties dialog for the selected alarm.
- **Remove**: Deletes the selected alarm.

## Alarm Properties
The Alarm Properties dialog defines the behaviour of an alarm. It includes two tabs:
- **Trigger**: Defines the condition that activates the alarm.
- **Action**: Specifies what happens when the condition is met.
### Trigger Tab
The trigger is a logical formula comparing one or more Measurement Parameters with each other or with a constant.
- Use mathematical operators to build the condition.
- Example: `RPM > 8000 AND Throttle > 90%`

### Action Tab
Defines the response when the trigger condition becomes TRUE. Multiple actions can be combined.

**Available Actions**
- **Display a Message** (default: on)
- **Jump to a Page** (default: off)
- **Emit a Sound** (default: off)
**Message Panel**
- **Display warning message**: Shows message while condition is TRUE.
- **Use alarm condition for message text**: Uses trigger formula as message.
- **Message Text**: Custom message if above option is disabled.
**Goto Page Panel**
- **Goto page**: Jumps to selected page when condition is TRUE.
- **Page name**: Select from dropdown list.
**Sound Panel**
- **Sound alarm**: Plays audible alert.
- **Test**: Play/stop alarm sound.
- **Default**: Use system default tone.
- **Custom**: Use selected `.wav` or `.mp3` file.
- **Repeat**: Sound repeats until condition clears.
- **Duration**: Sound plays for set time (in seconds).
- **Reset**: Delay before alarm can restart while still active.
---
# Overview
System Monitor is a configuration and monitoring tool used in TAG systems to manage how Electronic Control Units (ECUs) and other data logging devices acquire and store data. It supports both live and offline data acquisition workflows and integrates with ATLAS for analysis.
## Key Functional Areas
System Monitor provides tools grouped into two main categories:
- **Logging**: Configure how data is acquired and stored by the ECU, including live streaming, memory-based logging, and telemetry.
- **Sensors**: Set up and calibrate sensors connected to the ECU, including both software-calibrated and externally configured sensors.
## Logging Methods
System Monitor supports three primary logging methods:
- **Live Logging**: Real-time data acquisition via wirelink.
- **Remote Logging**: Data stored in DATALab memory for later upload.
- **Burst Logging**: High-speed data stored in Burst memory, often used with Wide Band Telemetry.
Each method has its own configuration tools and memory management strategies.
## Telemetry Support
TAG systems support two types of telemetry:
- **Narrow Band (Continuous)**: Low data rate, not configured via System Monitor.
- **Wide Band (Burst)**: High data rate, configured via Burst Logging tools.
---
# Overview
System Monitor provides comprehensive tools to configure how data is logged by an ECU or other data logging device. Logging is the process of acquiring data from measurement parameters and storing it for analysis, either live or post-session.
## Logging Categories
System Monitor supports three main logging methods:
- [**Live Logging**](live-logging.md): Sends data directly to System Monitor via wirelink, without storing it in the ECU.
- [**Remote Logging**](remote-logging.md): Stores data in DATALab memory for later upload.
- [**Burst Logging**](burst-logging.md): Stores high-frequency data in Burst memory, also used for Wide Band Telemetry.
Each method has its own configuration tools and session management features.
## Memory Allocation
TAG systems use two types of memory for data logging:
### Burst Memory
- Designed for high-speed logging of engine parameters.
- Triggering is simple and data is collected at the highest rate supported by the hardware.
- Configured via the Burst Logging configuration.
### DATALab Memory
- Used for chassis parameters that require lower sampling rates.
- Offers versatile triggering and configurable sampling rates.
- Configured via the Remote Logging configuration.
## Session Generation
Sessions represent the data collected during a test or race. They can be generated in three ways:
### Live
If the ECU is On-Line (in a testbed situation for example), a Session file can be generated which is suitable for analysis by ATLAS. The characteristics of the Session file are set using the Live Logging configuration.
!!! note
The Session data generated by System Monitor Version 7 is a single file in the format used by ATLAS Version 7. It is not compatible with ATLAS Version 6, which uses a different format.
### Upload
If Data Logging is used, System Monitor can configure the ECU to choose the parameters to be included in the session as well as the trigger and sample rate characteristics.
System Monitor does not have any direct involvement in generating the Session files. They are created by uploading the data from the ECU into ATLAS.
### Telemetry
Data is transmitted from a moving vehicle during the test session. System Monitor does not have any direct involvement in generating the Session files. ATLAS receives the data and analyses it live. ATLAS generates a Session file when Telemetry stops.
TAGtronic systems support two types of telemetry:
- **Narrow Band (Continuous)**: Low data rate telemetry that sends data continuously using low frequency radio. System Monitor is not used to configure this type of telemetry.
- **Wide Band (Burst)**: High data rate telemetry that sends data in bursts using high frequency (Microwave) radio. Data is logged into the Burst Memory, the contents of which are transmitted in each burst. System Monitor is used to configure this type of telemetry using the Burst Logging configuration.
---
# Live Logging
Live Logging is the process by which System Monitor obtains data from a connected ECU. The Live Logging Configuration serves two purposes in System Monitor:
- Obtains data for display in the current Desktop so it must include all the parameters that have been selected for display. If there is no Live Logging Configuration File in the Project, all the parameters are available for display.
- Selects the parameters to be included in a Session.
The live logging functionality in System Monitor captures slow row data. Therefore, to view it in ATLAS, ATLAS must be configured to display slow row parameters.
To configure Live Logging select `Logging > Live Configuration`.
### Session Tab
Use the Session tab of the Configure Live Logging dialog box to edit the characteristics of the Session that is created by System Monitor.
- **Files Generated Panel**:
- **Next Session Filename**: Displays the name and path of the file to be created for the Session. The default filename format is `SESSnnn.SSN` (where `nnn` starts at `000` and increments with each recorded session). Files are stored in the `\Sessions\` subdirectory under the Customer Base directory, which is automatically created when you create a new project.
- **Multiple Shot Sessions**: When enabled, records the number of sessions specified in the **Number of Shots** field. Each session is recorded automatically when trigger conditions are met, with unique filenames generated by incrementing the last three digits. When disabled, only one session is recorded when trigger conditions are met. This option has no effect if triggering is set to Manual on the Trigger Timing tab.

### Trigger Timing Tab
Use the Trigger Timing tab of the Configure Live Logging dialog box to set the size of the Session and the point in time that the trigger occurs in the data.
#### Logging Time
- The **Logging Time** is the length of time taken to log the session and is shown as Hours:Minutes:Seconds.
- Default Logging Time: 10:00 (ten minutes).
#### Mode panel
Select where the trigger appears in the recorded session data:
- **Manual** — The trigger is not used.
- **Start Logging** — The session starts when the Trigger Condition is TRUE and ends when the Logging Time has elapsed.
- **Stop Logging** — The session ends when the Trigger Condition is TRUE; the session length is defined by the Logging Time.
- **Pre and Post** — Partition the Logging Time into a Pre-trigger period and a Post-trigger period:
- Use the **Pre trigger time** and **Post trigger time** text boxes to set the durations, or adjust the slider between them to automatically partition the Logging Time.
- If editing the text boxes directly, ensure Pre + Post = Logging Time.
- The slider provides a quick visual partition; the text boxes allow precise control.
#### Disk Space in bytes panel
The panel displays read-only information about storage for the session:
- **Required** — Amount of disk space required to store the session, calculated from Logging Time, enabled parameters and their sampling intervals.
- **Free** — Amount of free space available at the session storage location.
!!! note
To capture data before the trigger condition is met, System Monitor continuously acquires data into a buffer sized to hold all data for the entire Logging Time so that pre-trigger data can be written when the trigger occurs.

### Trigger Condition Tab
Use the Trigger Condition tab of the Configure Live Logging dialog box to define the condition that acts as a trigger for the recording of the Session. A session is recorded according to the settings in the Trigger Timing tab. The trigger condition is a logical formula created from one or more Measurement Parameters combined by Mathematical Operators.

Live Logging can record a Session in two ways:
- Manual — Manual is selected as the Mode in the Trigger Timing tab.
- Automatic — A Trigger is selected as the Mode in the Trigger Timing tab.
The Status Bar indicates the status of recording as follows:
- **Recording OFF** — The Session is not being recorded.
- **Recording ON** — The Session is being recorded.
- **Trigger Pending** — Waiting for the trigger condition to become TRUE.
Make an Automatic Recording:
1. Select a Trigger as the Mode in the `Trigger Timing` tab.
2. Close the Live Logging Configuration dialog box.
3. Select `Logging > Trigger Enable`.
4. Select `ECU > On Line` to put the ECU On-Line.
5. Recording starts and stops automatically according to the settings in the `Trigger Timing` tab.
Recording can also be stopped by selecting `Logging > Recording` or by taking the ECU Off-Line.
---
# Remote Logging
Remote Logging is the process by which an ECU, stores data in DATALab Memory while not connected to System Monitor.
System Monitor can be used to edit the logging configuration in the ECU. To do this it is necessary to download the logging configuration from System Monitor. Similarly, to modify an existing logging configuration in the ECU, that configuration must first be uploaded to System Monitor.
Remote Logging Configuration is done in the Configure Remote Logging dialog box. To open the dialog box, select: `Logging > Remote Configuration`.
### Configure Remote Logging Dialog
Use the Configure Remote Logging dialog box to define the characteristics of the channels used to store data in the ECU. Click the information icons for context-sensitive help on the various elements of the dialog.

#### Memory end strategy panel
The Memory end strategy applies to all channels. Two strategies are available:
- **Stop when full** — Data is logged from the start trigger until either the stop trigger occurs or the ECU memory is full.
- **Wrap** — Data is logged from the start trigger until the stop trigger occurs. If the available memory is exceeded, new data overwrites the oldest data in memory so the memory always contains the most recent logged data. Use this strategy to analyse data leading up to a specific event.
#### Driver push button panel
Driver push buttons (dash or steering-wheel mounted) can be configured as either a trigger condition or to clear the ECU data logging memory. Options:
- **Button on clears logged data** — Pressing the driver push button clears the ECU data logging memory. If this option is used on the Channel Trigger dialog for any channel, that portion of the trigger condition will not operate.
- **Button on used as a trigger condition** — The driver push button is available as a trigger input for Channel Trigger conditions.
- **Button disabled** — The driver push button has no effect. If this option is used on the Channel Trigger dialog for any channel, that portion of the trigger condition will not operate.
#### Logging duration and rate
- The remote logging session duration is displayed on the Logging Duration panel as Hours:Minutes:Seconds and as a number of laps. The calculation is based on the sample rates of all enabled parameters across all channels and the settings in the Logging Duration dialog. Click `Setup` to open the Logging Duration dialog.
- The Logging and Telemetry displays indicate the required update rate for all channels. These values are calculated from the number of enabled parameters across all channels and their individual update frequencies.
#### Channel properties and configuration
- Remote Logging Configuration targets the DATALab logging system. DATALab provides eight channels that can be configured independently.
- Add parameters using `Parameters` to open the Select Parameters dialog. Maximum parameters allowed: 512. The number currently loaded is shown by the Logging slots used value.
- Each parameter is available on all eight channels. When a parameter is added it is disabled by default; to log it you must set a sampling frequency.
- The same parameter can be logged at different frequencies on different channels so it can be sampled at different rates under different conditions (each channel may have a different trigger). In ATLAS, parameter data from different channels can be combined to achieve better resolution.
| Column | Description |
|--------|-------------|
| **Parameter** | The parameter name. |
| **Description** | The parameter description. |
| **Application** | The application associated with the parameter. |
| **Bytes** | Size of the parameter in bytes. |
| **Prime** | Prime parameters are defined in the ASAP file. Prime parameters are logged continually in Channel 1 and cannot be disabled in that channel. An asterisk in the Prime column indicates a Prime parameter. Note: The Parameter, Description, Application and Prime columns can be toggled on and off using context menu commands. |
| **Channels** | Sampling frequency for the parameter on that channel. `---` indicates logging is disabled for the parameter in that channel. Note: If a cell background is red, the selected frequency is higher than the maximum refresh rate of the parameter. |
#### Context menu commands
With one or more cells selected, these context menu commands are available:
- **Frequency** — Sub-menu to select a logging frequency for the selected parameter cells.
- **Cycle** — Log the selected parameter once per engine cycle. Cells affected display `1 Cycle`.
- **Engine Segment** — Opens the Synchro Pattern dialog to select which engine segments to log the selected parameter. Cells affected display ``.
#### Controls
Control buttons apply to the currently selected cell(s). With multiple cells selected you can apply a command to:
- **Row** — e.g., enable a parameter in all 8 channels.
- **Column** — e.g., set the same frequency for all parameters in a channel.
- **Block** — e.g., enable parameters in a subset of channels.
Selection:
- Select multiple cells by click-and-drag or with keyboard arrow keys.
- To select all channels for a parameter, click the parameter name in the Parameter column.
| Button | Behavior |
|-----------------|--------------------------------------------------------------------------------------------------------------------|
| **Enable** | Enables the selected parameters in the selected channels. If a frequency was previously set it is reinstated; if the parameter was previously disabled the frequency is set to 100 Hz. |
| **Disable** | Disables the selected parameters in the selected channels. The DELETE key has the same effect. |
| **Set freq** | Opens the Set Uniform Frequency dialog. Set the sampling frequency for the selected parameters in the selected channels. |
| **Freq +/-** | Increases/decreases the frequency of selected parameters in the selected channels to the next valid frequency. If the parameter is disabled in that channel the previous value is recalled and increased/decreased. If no prior value was set, the default of 100 Hz is assumed and adjusted. Keyboard shortcuts: `+` and `-`. |
| **Set Trigger** | Opens the Channel Trigger dialog where start and stop triggers for the selected channel are defined. |
| **Channel** | Opens the Channel dialog for the selected channel. Use this to edit the channel name and select whether the channel is used for Telemetry, logging to the unit, or both. |
| **Arrange** | Opens the Arrange Channels dialog. Use this to select which channels are logged and change the channel order in the grid. |
| **Row example** | Enable a parameter in all 8 channels. |
| **Column example** | Set the same frequency for all parameters in one channel. |
| **Block example** | Enable parameters in a contiguous subset of channels. |
### Remote Logging - Duration
System Monitor calculates the duration of the Remote Logging session and displays it on the Channel Overview tab in hours:minutes:seconds and number of laps. The calculation is based on the sample rates of all enabled parameters in all channels and information set in the Logging Duration dialog.

To open the Logging Duration dialog, click `Setup` in the Configure Remote Logging dialog.
!!! note
These settings are only used for calculating the Logging Duration display; they do not affect the logging configuration.
#### Logging Duration Settings
- **Logging Memory** — Size of the memory available for logging.
- **Out Lap time** — Estimated duration of the out lap in seconds. One out lap is included in the Duration display. The right-hand value shows the volume of memory required to log data for that time period.
- **In lap time** — Estimated duration of the in lap in seconds. One in lap is included in the Duration display. The right-hand value shows the volume of memory required to log data for that time period.
- **Typical lap time** — Estimated typical duration of a flying lap in seconds. This value is used to calculate the number of laps shown in the Duration display.
- **Row data freq** — Average sample rate of Row data. The right-hand value shows the volume of memory required to log Row data for the entire session. This value is subtracted from the memory available for configured logging.
- **Average RPM** — Estimated average RPM.
The Duration calculation can allow for channels in which sampling is not continuous.
### Remote Logging - Channel Trigger
Use the Channel Trigger dialog to define the start and stop triggers for a channel. To open the dialog, click `Set Trigger` on the Channel Overview tab of the Configure Remote Logging dialog.

#### Start and Stop Trigger Panels
The Start and Stop triggers both have the same format, consisting of three conditions with the following relationship:
```
Condition 1 OR (Condition 2 AND Condition 3)
```
#### Condition Options
Each condition is defined by a row. The left-hand drop-down list has the following condition options:
- **On data** — When selected, the Select Trigger Parameter dialog opens to enable parameter selection. Only parameters included in the current Remote Logging Configuration are available for selection. Selecting On data enables the other fields in the row.
- **Driver push button** — The condition is TRUE when the driver presses the button. For this condition to work, the Driver push button option on the Remote Logging - Channel Overview tab must be set to **Button on used as a trigger condition**.
- **Ignition on** — The condition is TRUE when the engine ignition is switched on.
- **Lap trigger** — The condition is TRUE when the ECU receives a signal from the Lap Trigger.
- **No condition** — Fixed at FALSE for Condition 1 and TRUE for Condition 2 and Condition 3. This ensures that selecting No Condition does not override the other conditions.
#### On Data Settings
When **On Data** is selected as a condition, all fields are enabled:
- **Name** — The name of the selected parameter.
- **Comparison Operator** — Select the operator from the drop-down list:
- `=` — The condition is TRUE when the parameter value exactly equals the test value.
- `<` — The condition is TRUE when the parameter value is less than the test value.
- `>` — The condition is TRUE when the parameter value is greater than the test value.
- **Test Value** — Enter the test value. Parameter units are shown next to this field where appropriate.
- **Condition repeat** — This field is enabled for all condition types. Enter the number of times the condition must occur before it is considered TRUE. The default is 1.
#### Start/Stop Post Trigger
The effect of the trigger is delayed by the time (in milliseconds) set in the Start/Stop Post Trigger text boxes. The default is 0. Entering a negative value enables a pre-trigger delay.
#### Settings Panel
- **Trigger re-arms after stop trigger** — When enabled, a set of data will be logged every time the trigger conditions are met. When disabled, only one set of data will be logged.
- **Multiple triggers** — Calculates the Duration shown on the Channel Overview tab. This setting does not affect the logging configuration. When enabled, the **Triggers/lap** and **Trigger duration** settings are used to estimate the time required to log the data. When disabled, the duration is calculated assuming continuous parameter logging.
- **Triggers/lap** — Estimate of the expected number of times the trigger will be activated in each lap.
- **Trigger duration** — Estimate of the average length of time that data will be logged each time the trigger is activated.
### Arrange Channels
The Arrange Channels dialog controls which channels are used for logging and the order in which they are displayed in the Configure Remote Logging dialog.

To disable a logging channel, select the check box adjacent to the channel name and click `OK`. The channel column is removed from the Configure Remote Logging dialog.
To change the order in which channels are displayed, select a channel and click `Up` or `Down` to move it up or down the channel list. Click `OK`. The channel columns are rearranged in the Configure Remote Logging dialog accordingly.
### Synchro Pattern
The Synchro Pattern dialog determines which engine segments a parameter is logged in.

To open the Synchro Pattern dialog, select `Engine Segment` from the Configure Remote Logging dialog.
The selections apply to the parameters selected in the Configure Remote Logging dialog. Select which segments to log by selecting the appropriate check boxes.
---
# Burst Logging
Burst Logging is the process by which an ECU stores data in Burst Memory while not connected to System Monitor. In some types of ECU, the content of the Burst Memory can be transmitted at intervals using Wide Band Telemetry. Logging menu options enable Burst Logging Configuration in the ECU.
In order to change the logging configuration in the ECU, it is necessary to download it from System Monitor. Similarly, to modify an existing logging configuration in the ECU, that configuration must first be uploaded to System Monitor.
When ATLAS reads the data supplied by the ECU, it needs information about the Burst Logging Configuration. This information is supplied by System Monitor in a special export format that can be read by ATLAS.
To open the Burst Logging Configuration select: **Logging > Burst Configuration**.
!!! note
If this menu item is not available, a new Burst Logging Configuration File must be created. Burst Logging Configuration is only available if the relevant Customer Base has permission, as set in **Advanced Settings**.
The dialog box consists of the following tabs:
- **Parameters** - Select the parameters to be included in the Session that is created when the contents of the Burst Memory are uploaded to ATLAS.
- **Triggers** - Set the trigger conditions to start and stop data logging.
- **Session** - Edit the characteristics of the Session that is created when the contents of the Burst Memory are uploaded to ATLAS.
## Export
When ATLAS reads the data supplied by the ECU, it needs information about the Burst Logging Configuration. This information is supplied by System Monitor in a special export format that can be read by ATLAS.
A Burst Configuration Export file is created automatically every time a Burst Logging Configuration is downloaded to an ECU. The file name is generated from the timestamp in the ECU. The file name is used by ATLAS to link the session to the configuration file so it must not be changed. The path is defined in the **Advanced Settings** dialog box - select: **Tools > Advanced Settings**.
To create a Burst Configuration Export file at any time select: **Logging > Burst Export**.
## Parameters
Use the Parameters tab of the Configure Burst Logging Dialog to edit the characteristics of the Session that is created when the contents of the Burst Memory are uploaded to ATLAS.

**Display Control**
The Display drop-down list determines how the Parameter List is displayed. The options are:
- **Parameters** - Shows all the selected parameters with a row for each one.
- **A Blocks** - Shows all the available A blocks with a row for each one.
- **B Blocks** - Shows all the available B blocks with a row for each one.
**Size and Logging Time Display**
The following information is displayed:
- **Size** - The size of the Logging Memory in the ECU. Taken from the ASAP file.
- **Logging Time** - The duration (in hours:minutes:seconds) of logging that will fill the memory. Calculated from the Logging Intervals and the Size of the memory.
- When **Parameters** is selected in the Display drop-down list, logging time is calculated from the Parameter intervals.
- When **A Blocks** or **B Blocks** is selected in the Display drop-down list, logging time is calculated from the block intervals even if the blocks do not have any parameters assigned to them.
**Parameters List**
| Column | Description |
|---|---|
| Parameter | Parameter name. Only shown when "Parameters" is selected in the Display drop-down list. This column can be hidden using the context menu. |
| Description | Parameter description. Only shown when "Parameters" is selected in the Display drop-down list. This column can be hidden. |
| Application | The Application associated with the Parameter. Only shown when "Parameters" is selected in the Display drop-down list. This column can be hidden. |
| Block | The block to which the Parameter has been assigned. '---' indicates the Parameter is not assigned to a block. |
| Interval | The sampling interval for the Parameter. When a Parameter is assigned to an empty block, the interval is set to the lowest available value. '---' indicates logging is disabled for the Parameter. |
| Bytes | The size of the Parameter in bytes. Only shown when "Parameters" is selected in the Display drop-down list. |
| Bytes Available | The space available in bytes for assigning Parameters. Only shown when "A Blocks" or "B Blocks" is selected in the Display drop-down list. |
**Adding Parameters**
Click **Parameters** to open the **Select Multiple Parameters** dialog box. Use this to add and remove Parameters. The number of Parameters that you can add depends on their type and how they are assigned to blocks.
If the list is empty when parameters are added, use **Auto Assign** to place all the Parameters in B blocks. If the list is not empty, the new Parameters are added using the following rules of precedence as the available space is filled up:
1. Same block as currently selected Parameter
2. New block of the same type (A or B) at the same interval
3. Other type of block at the same interval
4. Same type of block at higher interval
5. Other type of block at higher interval
6. Not assigned
If **A Blocks** or **B Blocks** is selected in the Display drop-down list, and one or more blocks are selected, the Parameters are assigned to the selected blocks.
**Set Block**
Opens the **Select Burst Block** dialog box. Only available if **Parameters** is selected in the Display drop-down list.
The drop-down list shows all the blocks which have sufficient space to accept the selected Parameter(s). Click OK to assign the selected Parameters to the selected block.
If “---“ is selected, the Parameter assignments are deleted and the list shows in the Block column. The Parameter is not logged.
**Auto Assign**
Opens the **Assign Burst Blocks** dialog box. Only available if **Parameters** is selected in the Display drop-down list.
The selected Parameters are assigned (in the order that they appear in the list) to the selected type of block, in numerical order of blocks.
**Set Interval**
Features:
- The interval applies to a complete Block. The intervals of Parameters that share a block with the selected Parameters are also changed.
- The interval can be set to “---“, which prevents the Parameter from being logged while retaining its block assignment.
- Set Interval only operates on Parameters that are assigned to blocks.
- If **A Blocks** or **B Blocks** is selected in the Display drop-down list, the interval is applied to the selected block or blocks. The blocks do not have to have any parameters assigned to them.
- If **A Blocks** or **B Blocks** is selected in the Display drop-down list, the interval is applied to the selected block or blocks. If multiple blocks are selected, the intervals are increased sequentially in each block in the list. The blocks do not have to have any Parameters assigned to them.
**Interval +/-**
Increases/decreases the interval of the selected Parameters to the next valid interval. This feature only operates on Parameters that are assigned to blocks and do not have an interval set to “---“.
You can also use the plus and minus keyboard equivalent keys.
## Triggers tab
Use the Triggers tab to set the trigger conditions to start and stop data logging.

**Start Panel**
- **Driver pushes button** - When selected, logging starts when the driver presses the control button that is configured for use with data logging. The default is selected.
When **Driver pushes button** checkbox is cleared, the following options are available. Select one of the options.
- **Ignition on** - When selected, logging starts when the ignition is switched on. A delay of up to 120 seconds can be entered, to a resolution of 0.1 seconds. The default is 0.
- **Engine started** - When selected, logging starts when the engine is started. A delay of up to 120 seconds can be entered, to a resolution of 0.1 seconds. The default is 0.
- **Engine speed** - When selected, logging starts when both Engine Speed and Throttle Position have exceeded the specified thresholds. This is the default.
Enter Speed as an integer, between 0 to 20000 rpm, and Throttle position as a percentage to a resolution of 0.1%. The default for both of these is 0.
**Stop Panel**
- **Speed below** - When selected logging will stop when the engine speed has fallen below the specified threshold. Enter Speed as an integer from 0 to 20000 rpm. The default is 0.
- **Memory end strategy** - Two strategies are available:
- **Stop when full** - Data is logged from the start trigger until either the stop trigger occurs or the ECU memory is full. This is the default.
- **Wrap** - Data is logged from the start trigger until the stop trigger occurs. If the available memory is exceeded, new data overwrites the oldest data in the memory, so the memory always contains the most recent logged data. Use this strategy if you want to analyze data leading up to a specific event.
## Session tab
Use the Session tab to edit the characteristics of the Session that is created when the contents of the Burst Memory are uploaded or transmitted to ATLAS.
For ECUs that utilize Burst memory for Wide Band Telemetry, the following controls are available:
- **Car ID** - The car is given an ID number to distinguish it from other cars (For example, cars in the same team using the same telemetry system). The number entered here must match the ID of the car. The value is an integer from 1 to 4.
- **Transmitter** - When selected, the transmission of data via telemetry is enabled.
- **Frequency** - The value in this text box is used to set the radio frequency of the transmitter if the transmitter is software configurable. Ensure that the value is within the operating range of the transmitter.
- **Multi-Burst File** - Some versions of ATLAS can configure the retransmission of data in multi-burst telemetry. If your version of ATLAS has this facility, it will generate a Multi-Burst Coverage File (*.mbc). The coverage data is downloaded to the ECU with the Logging Configuration.
If you do not have a Multi-Burst Coverage File this field is empty.
## Blocks
The Burst Logging blocks are set up in the Parameters tab of the Burst Logging dialog box.
The hardware design imposes restrictions on the way the Logging Memory is used and on the speed of logging. System Monitor is configured to automatically apply rules regarding such restrictions. Blocks are automatically filled and any attempts to select more than the maximum number of parameters are prohibited.
The following describes the way calculations are performed.
There are two types of Parameter:
- **WORD** - Single WORD parameter: The parameter value is coded as one WORD.
- **DWORD** - Double WORD parameter: The parameter value is coded as two WORDs.
A DWORD parameter uses exactly twice as much memory as a WORD parameter, so that a given amount of memory can only accept half as many DWORD parameters as WORD parameters.
Memory is arranged in Blocks. There are two sizes of Block:
- **A Blocks** - Each A Block can contain 4 WORD size parameters, 2 DWORD parameters or a mixture of both.
- **B Blocks** - Each B Block can contain 8 WORD size parameters, 4 DWORD parameters or a mixture of both.
The number of Blocks is restricted as follows:
| Max No. of Blocks | Max No. of WORD Parameters |
|--------------------|----------------------------|
| A Blocks | 64 | 256 |
| B Blocks | 64 | 512 |
Each DWORD Parameter takes up two WORD parameter places.
The memory is ordered on data type. It is filled first with DWORD parameters then WORD parameters. For example, if 7 DWORD parameters and 5 WORD parameters are assigned to B blocks, the blocks would be filled as follows:
| DWORDS | WORDS | Empty | Total WORD Equivalent |
|--------|-------|-------|-----------------------|
| 1st Block | 4 | - | - | 8 |
| 2nd B Block | 3 | 2 | - | 8 |
| 3rd B Block | - | 3 | 5 | 8 |
| Total | 7 | 5 | | |
## Intervals
The Logging Interval for each Burst Logging block is set up in the Parameters tab of the Burst Logging dialog box.
The hardware design imposes restrictions on the way the Logging Memory is used and on the speed of logging. System Monitor is configured to automatically apply rules regarding such restrictions and automatically calculates the minimum interval.
There is a minimum logging interval (fastest logging rate) for each Block. Parameters can only be logged in complete blocks even if a block is not full. Logging is ECU time synchronous.
Each block takes 1ms to log therefore:
**Minimum interval (ms) = number of blocks with parameters assigned**
A blocks and B blocks are independent and have different minimum intervals.
If higher rate sampling is required (reduced interval) for selected parameters, the minimum interval can be increased by doing one or more of the following:
- Increase the interval of some other parameters
- Move parameters from A blocks to B blocks or from B blocks to A blocks
- Set the interval of some other parameters to “---“
- Set the block assignment of some other parameters to “---“
- Remove some other parameters
---
# Remote Configuration Compare
Remote Configuration Compare is the process that allows the comparison of the existing project remote logging configuration to an additional existing configuration file.
The configuration details can be compared and merged as required.
## Remote Configuration Compare Dialog
Remote Logging Compare is done in the Logging Configuration Compare dialog box. To open the dialog box, select: **Logging > Remote Configuration Compare**.
On opening, the existing project logging configuration file is displayed. To compare with an additional configuration, click the **Load** button and select the required configuration. Both files will then be displayed for comparison and merging.

### Options
- **Load**: Loads a configuration to enable comparison and merging.
- **Unload**: Unloads the compare configuration.
- **Logging Slots**: Displays the logging slots used in both the current configuration and, if loaded, the compare configuration.
- **Show parameters with differences only**: When selected, only differences between the configurations are displayed.
- **Commit**: When selected, any outstanding merging will be committed into the existing project remote logging configuration.
- **Reset**: When selected, any outstanding merging will be undone. Once committed, a merge cannot be undone.
## Config Tab
The config tab displays the differences between the parameter logging rates for the two configurations, with a color scheme used to highlight any differing rates.

The grid consists of the following columns:
- **Parameter**: The parameter name. (Can be toggled on and off via the context menu.)
- **Description**: The parameter description. (Can be toggled on and off via the context menu.)
- **Application**: The application associated with the parameter. (Can be toggled on and off via the context menu.)
- **Bytes**: The size of the parameter in bytes. (Can be toggled on and off via the context menu.)
- **Prime**: A parameter defined as a Prime Parameter in the ASAP file. Prime Parameters are logged continually in Channel 1 and cannot be disabled in that channel. An asterisk in the Prime column indicates a Prime Parameter. (Can be toggled on and off via the context menu.)
- **Channels**: The sampling frequency for the parameters on that channel.
The header displays the channel title and type for each of the configurations.
### Logging Rate Indicators
- Logging rate in secondary configuration higher than in master.
- Logging rate in secondary configuration lower than in master.
- Logging rate in secondary configuration same as in master.
- Logging rate exists in master only.
- Logging rate exists in secondary only.
- Logging rate merged from secondary into master.
To merge a value from the secondary configuration, select the appropriate cell or cells and right-click to display the merge option. The merge option is only available if there are differences between the values selected. If items within the selection are already merged, an undo option will be available.
### Merge / Undo Selections
- **Channel Title Merge**: Right-click in the first two header rows and from the menu select 'Merge Channel title into Master'. This will set the master channel title to the same as the secondary.
- **Channel Type Merge**: Right-click in the lower two header rows and from the menu select 'Merge Channel type into Master'. This will set the master channel type to the same as the secondary.
- **Row Merge**: Right-click in any header row and from the menu select 'Merge into Master'. Set the logging rates of all channels for the parameter selected to the same as the secondary.
- **Channel Merge**: Right-click in any header row and from the menu select 'Merge Channel into Master'. Set the logging rates of all parameters in the channel to the same as the secondary.
- **Cell Merge**: Select one or more cells in the grid and from the menu select 'Merge into Master'. Set the logging rates of all cells selected to the same as the secondary.
## Triggers Tab
The triggers tab displays the differences between the triggers for the two configurations.

### Merging Triggers
- **<<**: Selecting the '<<' option will merge the secondary trigger into the master. Can only be selected if a difference between the triggers exists.
- **X**: Selecting the 'X' option will undo any merge of the trigger. Can only be selected if the trigger has been merged.
- **Next**: Selecting 'Next' will cycle to the next trigger.
- **Prev**: Selecting 'Prev' will cycle to the previous trigger.
---
# Logging Configuration
## Session Details
Session Details identify the Session and include information to assist in the analysis of session data. Session details are required for Live Logging, Remote Logging, and Burst Logging.
To open the Session Details dialog box, click **Edit** on the Sessions tab of the Live Logging dialog box. The details are the same on the Remote Logging and Burst Logging dialog boxes.
### Read-only Session Details
- **Session** - The name of the Session File. For Live Logging this is set automatically. For Remote and Burst logging the file name is generated by ATLAS.
- **Serial Number** - Taken from the ECU hardware.
- **Session Start** - Taken from the clock of the system creating the Session file.
- **Session End** - Taken from the clock of the system creating the Session file.
### Editable Session Details
- Car
- Driver
- Circuit
- Race/Test
- Weather
- Notes
### Edit Session Details
1. Select an editable item with mouse or keyboard.
2. Click in the text box at the bottom of the tab or press **TAB** and enter any text in the box.
3. To accept the text: press **ENTER** or **TAB** or select another item with the mouse.
Session details are shown in ATLAS to help you identify the Session.
## Channels
To enhance the versatility of the logging process, parameters are grouped into Channels (sometimes known as Sets). Because channels correspond to physical storage locations in the Data Logging hardware, they are subject to various restrictions.
System Monitor recognizes the unit type from its Program Version and only offers the appropriate channel type. Individual units may have further restrictions (such as memory size limitations) which are recognized by System Monitor and used to further restrict available options and calculate sampling rates.
### Channel Types
**Raw Data**
Used in Live Logging to acquire data from an ECU. Parameters are acquired synchronously. The schedule is based on the PC timer with a minimum interval of 5ms. This time interval determines the rate at which parameter values are logged to disk. Since the ECU sends Parameter values at an unknown and variable rate, some values may be recorded into the session file more often than others.
The Parameters logged as Raw data are set by the embedded code independently of logging configurations. Any Parameter logged by a command from the embedded code instead of by a logging configuration is called a Fixed Parameter.
Fixed Parameters are typically those whose value does not change often, such as Battery Voltage, but any, and in some cases all, Parameters may be set as Fixed Parameters. Fixed Parameters are generally logged at a much slower rate than the Parameters in a logging configuration and are sometimes called Slow Raw data.
**Request Channel**
Used in Live Logging to acquire data from the CA-Card via CAN or direct connection. Parameter values are acquired asynchronously. The minimum acquisition interval is calculated based on the time to acquire each Parameter and the number of Parameters. You can set any time interval on or above this minimum.
**Non-ECU Request Channel**
A restricted form of the Request Channel. Used in Live Logging for Virtual Parameters.
**TAGtronic Channel**
Used in Burst Logging to acquire data from the Burst memory in an ECU.
**DATALab Channel**
Used in Remote Logging to acquire data from the DATALab memory in an ECU. Four independently triggered channels are available. A different sampling rate can be assigned to each Parameter.
## Logging Configuration Files
When a Logging Configuration is edited, the changes made are stored in a Logging Configuration file.
Whenever a New Project is created, a file directory is automatically generated for each logging configuration type - Live, Remote, and Burst. These directories are initially empty.
A new Logging Configuration file must be created before a Logging Configuration can be edited, or an existing Logging Configuration file can be opened.
To open a new Logging Configuration File, select: **File > New** to open the File New dialog box.
A Logging Configuration file can be saved. If you change a logging configuration, you are prompted to save the modified configuration when you close the project. To keep an old configuration, use the **Save As** command to save the modified configuration under a different name before closing the project.
Only one instance of each logging configuration type can be loaded into a project. If you have modified a configuration, you are prompted to save it when you create a New or Open an existing file.
Remote and Burst logging configurations can also be Uploaded from an ECU.
## Loading Configurations
The Remote logging, Burst logging, and External Inputs configurations are stored in and used by an ECU when it is working independently of System Monitor. To change a configuration in the ECU, it must be downloaded from System Monitor. Similarly, to modify an existing configuration in the ECU, that configuration must first be uploaded to System Monitor. This is not automatic and must be done manually using menu commands.
Separate commands are provided for Remote logging and Burst logging configurations on the Logging Menu and for External Inputs configurations on the Sensors Menu. Note that some hardware may have both types of logging configuration.
### Download
Transfers the configuration from System Monitor to the ECU.
Download only takes place if System Monitor detects an ECU that matches the Program Version used by the current project. The old configuration is overwritten.
### Upload
Transfers the configuration from the ECU to System Monitor.
Uploading overwrites the current configuration in System Monitor. If you have modified a configuration in System Monitor, you are prompted to save it when you select Upload.
Any parameter that is not defined by the current system description is discarded from the configuration. A warning will appear listing the parameters that have not been included in the upload.
---
# Overview
System Monitor includes tools to configure Controller Area Network (CAN) messages for data logging. These messages can be transmitted to external units or received and logged internally using CAN buffers.
## CAN FD Support
System Monitor supports **CAN FD (Controller Area Network with Flexible Data-rate)**, enabling higher-bandwidth CAN communication with data payloads up to **64 bytes** per message (compared to the classic CAN limit of 8 bytes). CAN FD is available on hardware units that advertise CAN FD capability in their controller descriptions. For configuration steps, see [CAN FD](configuration.md#can-fd).
## Configuration Dialog Box
The CAN Configuration dialog box is used to configure:
- Transmit CAN messages for logging by an external unit
- Receive CAN messages for logging internally using the CAN buffers
To open the dialog box, select: **Logging > CAN configuration**.
!!! note
- If the CAN Configuration menu option is not enabled, a new CAN Configuration file must be created or an existing CAN Configuration file opened. See **Creating New Files**, **Opening Files**.
- When a new CAN Configuration file is added to the project, there are no CAN messages configured initially. Messages can be configured manually or imported from existing files. See **Import/Export Buffers and Messages**.
- Creating or adding a CAN Configuration file to the project adds a **CAN Parameters** folder to the System Monitor Explorer. This folder contains CAN Parameters configured in the ECU, which can be associated with CAN Receive Messages. See **CAN Parameters**.

The CAN configuration dialog supports the use of up to 8 configurations. These can be loaded and unloaded as required and will be merged to create a single configuration.
- A main configuration must exist in the project, but any additional configurations can be loaded, deleted, or set active in the dialog.
- Any errors from merging the selected configurations are displayed below the file list.
Depending on the project, the FIA can sanction the use of an FIA supplied CAN configuration. In this case, a list of radio buttons allows the FIA configuration to be selected. This results in the defined CAN configuration being included in the logging configuration as a separate entity.
## CAN Configuration Explorer
The CAN Configuration explorer shows the CAN Buses configured for the connected unit:
- The ECU type is shown at the top with the available CAN Buses listed below it.
- The nodes available are defined within the ASAP file.
- With a CAN bus node selected, the configurable options available affect all Buffers and their associated CAN messages.
---
# CAN Configurations
## CAN Bus
With Customer Bus selected in the explorer, the configurable options available affect all Buffers and their associated CAN messages.
Expanding the Bus node displays the Buffers and CAN messages configured for the Bus.

**Customer Bus Panel**
| Option | Description |
|--------|-------------|
| **Buffer Count** | The number of Buffers available for configuration on the selected Bus. |
| **Global Mask** | The receive mask for all Buffers that do not have a configurable Receive Mask. *Note: Not all control units support a configurable global mask.* |
| **Link Speed** | Select a speed in kbits for the selected Bus from the drop-down list. This sets the arbitration-phase bit rate. |
| **CAN-FD Supported** | An indicator that appears when the connected controller supports CAN FD. This label is only visible on CAN-FD-capable hardware. |
| **Data Speed** | Select the CAN FD data-phase bit rate from the drop-down list. This is separate from the Link Speed (arbitration-phase bit rate). Available speeds are determined by the hardware controller. Only visible when the controller supports CAN FD. |
!!! note
The **Data Speed** dropdown and **CAN-FD Supported** label are only visible and enabled when the hardware unit reports CAN FD capability. On classic-CAN-only hardware, these controls are hidden.
**Parameter Block Panel**
Received Measurement Parameters for the CAN bus are stored in a single contiguous block of memory.
| Parameter | Description |
|-----------|-------------|
| **Ctrl Id** | The Control Id of the memory block. |
| **Parameter Address** | The start address of the memory block. |
| **Block Size** | The size of the memory block in number of blocks. |
## Buffers
With a Buffer selected, the configurable options available apply to that Buffer only.

!!! note
The CAN messages associated with this buffer are listed in the Messages node for this CAN Bus.
**Add a CAN Message to an Empty Buffer**
1. Select a Buffer
2. Click **Add**
3. In the Add MessageId dialog box, select a Message Id from the drop-down list and click **OK**
The CAN message is assigned to the selected Buffer. When a specific Message is selected in the explorer, the Buffer to which it is assigned is shown in the Message Details. A CAN message can only be assigned to one Buffer.
!!! note
Buffers can be configured individually as described above, or existing Buffer configurations can be Imported. See [Import/Export Buffers and Messages](#importexport-buffers-and-messages).
**Mode Panel**
Define the mode of the CAN messages configured for this buffer.
| Mode | Description |
|------|-------------|
| **Not Configured** | Any messages configured for this buffer will not be included in the logging. |
| **Receive** | CAN messages are in receive mode. |
| **Transmit** | CAN messages are in transmit mode. |
**Buffer Panel**
| Option | Description |
|--------|-------------|
| **Receive Mask** | Any bits that are zero in the Receive Mask are ignored when comparing a received dataframe's ID against the acceptance ID of the buffer. For example, if the receive mask is set to `0xFFFFFFF0` and ID of the first message is `0x210`, then the buffer will receive all messages in the range `0x210` to `0x21F`. *Note: Not all buffers have a configurable receive mask.* |
| **Rate** | The time between each message being transmitted in ms. |
| **Message Count** | The number of CAN messages configured for the selected Buffer. |
**Messages Panel**
The Messages Window lists the IDs of CAN messages currently configured for this buffer.
| Action | Description |
|--------|-------------|
| **Add** | Click to add a CAN message to the selected buffer. |
| **Delete** | Click to delete the selected Message Id. |

## CAN Messages
With the Messages node selected, the **New Message** button is displayed to allow new CAN messages to be added to the Configuration.
To add a CAN message, click **New Message** and enter a Message ID in the Add Message ID dialog box. The new message is added to the list.
!!! note
CAN messages can be added and configured individually as described above, or existing CAN Message configurations can be Imported. See [Import/Export Buffers and Messages](#importexport-buffers-and-messages).
To view the CAN messages configured for the CAN Bus, expand the Messages Node. With an individual CAN message selected, the configurable options apply to that message only. Use these commands to configure the CAN message and to add new Parameters as required.
**Message Panel**
| Option | Description |
|--------|-------------|
| **Message Id** | The unique CAN identifier for the selected CAN message. |
| **Description** | Enter a short description of the CAN message. |
| **CAN FD** | Enable this checkbox to mark the message as a CAN FD frame. Only available when the parent CAN bus supports CAN FD. |
| **Message Length** | Enter the length of the CAN message. For classic CAN messages the maximum is 8 bytes. When CAN FD is enabled, the maximum increases to 64 bytes and the control enforces valid CAN FD data lengths (0–8, 12, 16, 20, 24, 32, 48, 64). For CAN messages with multiplexed data, the length must be the same for all multiplexer values. |
| **Buffer** | The Buffer to which the selected CAN message is assigned. (Read only) |
| **Parameter Count** | The number of Parameters associated with the selected CAN message. |
| **Mode** | TRANSMIT / RECEIVE / NOT CONFIGURED - The Mode of the selected CAN message (the same for all messages in that Buffer). |
| **New Parameter** | Opens the Add Parameter dialog box. |
When CAN FD is enabled on a message:
- The message length range extends to 64 bytes.
- Stepping through the length field automatically snaps to the next valid CAN FD data length (e.g., incrementing from 8 jumps to 12, not 9).
- Messages are displayed with an **"FD"** label in the tree view (e.g., `Message FD - 0x1A3` instead of `Message - 0x1A3`).
**Multiplexed Panel**
Multiplexed CAN messages allow more measurement parameters to be received by a CAN buffer than can be packed into a single CAN message.
| Option | Description |
|--------|-------------|
| **Multiplexed** | Select this checkbox to multiplex some or all of the CAN message data. |
| **ByteOrder** | Select the byte order of the multiplexer: MSB First or MSB Last. |
| **StartBit** | Select the position within the CAN message data where the multiplexer value starts. |
| **BitLength** | The length, in bits, of the multiplexer value. Maximum length is 16. |
| **MultiplexerValues** | When transmitting this message, multiplexed messages in the range of 0 to Multiplexer Values - 1 will be sent. |
## Parameter Details
With a specific Parameter selected, the configurable options available apply to that Parameter only.

**Parameter Panel**
| Option | Description |
|--------|-------------|
| **Parameter** | The name of the Parameter. For received Parameters, this is the name displayed by System Monitor and ATLAS. For transmitted Parameters, this is the name of the parameter to be transmitted. |
| **Properties** | Open the Parameter Properties dialog box to edit the Parameter Properties. |
| **Start Bit** | Select the position within the CAN message data where the Measurement Parameter starts. For classic CAN messages the range is 0–63; for CAN FD messages the range extends to **0–511**. *Note: When MSB Last is selected as the Byte Order, the default Start Bit shows the normalised value. For a parameter at the start of a CAN Message, the Start Bit is shown as 0, although its underlying value is 7.* |
| **Bit Length** | Select the length in bits of the Measurement Parameter. Maximum length is 32. |
| **Value** | Select whether the Measurement Parameter is Signed, Unsigned, or Floating Point. If Floating Point is selected, the Bit Length must be set at 32. |
**Scaling Panel**
| Option | Description |
|--------|-------------|
| **Gain** | Set the gain for converting a scaled value into a raw value. |
| **Offset** | Set the offset for converting a scaled value into a raw value. |
**Scaling Formula:**
```
Raw Value = GAIN × Scaled Value + OFFSET
```
**Byte Order**
Select the byte order of the Measurement Parameter:
- **MSB First**
- **MSB Last**
### Multiplexer Panel
**ID**
If the message is multiplexed, the multiplexer ID defines which multiplexed messages the parameter will be in.
A Measurement Parameter can be defined in more than one multiplexed message, since the multiplexer ID is a combined value and mask:
- `0`, `1`, or `X` can be used for each bit in the multiplexer ID, where `X` means that bit does not matter
- For example, if a measurement parameter is in all messages with an even multiplexer value, the multiplexer ID should be set to `XXXXXXXXXX0`
**Value**
The Parameter is transmitted/received if the value equals the multiplexer value for the message currently being processed, after any bits in the mask are ignored.
**Mask**
Calculated from the entered multiplexer ID and defines which bits of the multiplexer value should be ignored when determining whether to include this parameter in the message.
## CAN Bit Definitions
For each Measurement Parameter and multiplexer value, the start bit, length, and byte order must be defined. Bits and bytes within a CAN message are numbered sequentially from left to right.
### MSB First Format Values
When a Measurement Parameter or multiplexer value is defined as **MSB_FIRST**, the start bit defines the location of the most significant bit. The progression of bits and bytes is to the right.

### MSB Last Format Values
When a Measurement Parameter or multiplexer value is defined as **MSB_LAST**, the start bit defines the location of the least significant bit. The progression of bits is to the left and the progression of bytes is to the right.

!!! note
- In an MSB Last word, the Start Bit is the last bit of the first byte. Whilst the Start Bit for the word at the start of a CAN message is bit 0, the Start Bit in terms of MSB is bit 7. When a Parameter is added to the CAN Message, the CAN Configure dialog automatically displays normalised values for the Start Bit. For example, if the Parameter appears at the start of a CAN Message, the value 0 is shown, although its underlying value is 7. The Start Bit of a 2nd Parameter is shown as 8, although its underlying value is 15, and so on.
- When a CAN message is exported, the saved Start Bit values are the actual values and not the normalised values shown in the dialog box. These can be seen in the Start Bit column of the .csv Export files.
## CAN Message Parameter Layout
The **Parameter Layout** dialog displays the byte grid for a CAN message, allowing you to visualise parameter placement within the data frame.
- Classic CAN messages display the existing 8-row (byte) grid.
- CAN FD messages display a **64-row** grid, covering the full 64-byte payload. The dialog supports vertical scrolling to navigate the larger layout.
Use the **Parameter Layout** button on the CAN Message configuration page to open the layout grid and verify parameter placement.
## CAN Parameters
When a CAN Configuration file is added to the project, a CAN Parameters folder is added to the System Monitor Explorer. This folder contains CAN Parameters configured in the ECU, which can be associated with CAN Receive messages.
!!! note
Parameters associated with Transmit CAN messages are not listed in the CAN Parameters folder. However, for a Parameter to be associated with a CAN Transmit message, it must exist in the ECU Measurement Parameters folder.
**Add a CAN Parameter**
To associate a new Parameter with a CAN message:
1. Select a message and click **New Parameter** to open the Add Parameter dialog box
2. **Name** - Enter the name of a Parameter to associate with the selected CAN message
- *Note: For a Parameter to be selected for a Transmit message, it must be listed in the ECU Measurement Parameters folder in the System Monitor Explorer.*
- Click to browse for a Parameter in the Select Parameter dialog box
3. Click **OK** to associate the Parameter with the selected CAN message
## Import/Export Buffers and Messages
Existing Buffer Configuration (.csv) files and Message Configuration files can be imported into the CAN configuration. Buffer and Message configurations can be exported from the CAN Configuration as .csv files.
!!! note
When importing Buffer Configuration files or Message Configuration files, all Buffer/Message configurations are overwritten by the imported file.
### Import/Export Buffer Configuration Files
1. Select **Logging > CAN Configuration** to open the CAN Configuration dialog box
2. Expand the CAN Bus and select **Buffers**
3. Right-click and select **Import Buffer** or **Export Buffer**
### Import/Export Message Configuration Files
1. Select **Logging > CAN Configuration** to open the CAN Configuration dialog box
2. Expand the CAN Bus and select **Messages**
3. Right-click and select **Import Messages** or **Export Messages**
### CAN FD Import/Export Notes
- **CSV/Text Export** — CAN FD messages are exported with an `fd` suffix on the message ID (e.g., `0x1A3fd` rather than `0x1A3`). Extended-frame identifiers remain compatible (e.g., `0x1A3fdx`).
- **CSV/Text Import** — The import parser recognises the `fd` suffix on message IDs and automatically creates CAN FD messages.
- **A2L / ASAP2 Import** — The ASAP2 parser now recognises the `TES_SUPPORTS_CANFD` and `TES_DATA_SPEEDS` keywords, allowing CAN FD bus descriptions to be imported from A2L files.
- **DBC Export** — DBC export includes the CAN FD flag, ensuring that exported DBC files correctly represent CAN FD message properties.
## CSV File Formats
Buffer and CAN message CSV import files must be formatted as described below.
**Buffer CSV File Format**
| Col | Name | Description |
|-----|------|-------------|
| 1 | Buffer | The number of the buffers in the CAN Bus. |
| 2 | Direction | Mode of the CAN messages configured for this buffer. TX = Transmit, RX = Receive, Blank = not configured. |
| 3 | RX Mask | The Receive Mask value, if one is configured for the buffer. Blank = not configured. |
| 4 | Rate[ms] | The time (ms) between each CAN message being transmitted. |
| 5 | Messages | The CAN message ID configured for the buffer. If more than one CAN message is configured, they must be comma-separated. |
**CAN Message CSV File Format**
Following a change in the representation of the Parameter Start Bit, v2 of the CAN Message CSV format is now in use. When parameters are set as MSB Last, the value in the .csv is now represented by the logical bit position.
v2 files are identified by the text `v2` as the first value in the header row. All exported files now conform to the new format; both formats can be imported.
| Col | Name | Description |
|-----|------|-------------|
| 1 | CAN ID | The CAN message ID. 11-bit IDs: 0 to 0x7FF. 29-bit IDs: 0 to 0x1FFFFFFF. CAN FD messages include an `fd` suffix (e.g., `0x1A3fd`); extended-frame CAN FD identifiers use `fdx` (e.g., `0x1A3fdx`). |
| 2 | Message Length | The CAN message length. |
| 3 | Start Bit | Multiplexer messages - the position within the CAN message data where the multiplexer value starts. |
| 4 | Length | Multiplexer messages - the length, in bits, of the multiplexer value. Maximum length is 16. |
| 5 | Byte Order | Multiplexer messages - the byte order of the multiplexer: MSB First or MSB Last. *Note: If the Message is not multiplexed, columns 3, 4, and 5 are blank.* |
| 6 | Parameter Name | The name of the Parameter associated with the CAN message. If more than one, subsequent parameters are listed on a new line. |
| 7 | Start Bit | The position within the CAN message data where the Measurement Parameter starts. |
| 8 | Length | The length in bits of the Measurement Parameter. Maximum length is 32. |
| 9 | Multiplexer ID | The multiplexer ID defines which multiplexed messages the parameter will be in. |
| 10 | Signed | Whether the Measurement Parameter is signed: YES or NO. If Floating Point, this column must be NO. |
| 11 | Floating Point | Whether the Measurement Parameter is Floating Point. |
| 12 | Byte Order | The byte order of the Measurement Parameter: MSB First or MSB Last. |
| 13 | Scaling Gain | Parameter property. The Gain set for converting a scaled value into a raw value. |
| 14 | Scaling Offset | Parameter property. The Offset set for converting a scaled value into a raw value. |
| 15 | Description | Parameter property - Description. |
| 16 | Display Format | Display format. |
| 17 | Units | Display units. |
| 18 | Lower Limit | Lower value limit. |
| 19 | Upper Limit | Upper value limit. |
| 20 | Identifier | CAN Parameter unique identifier. |
| 21 | Display Limit Low | Lower display limit. |
| 22 | Display Limit High | Higher display limit. |
## CAN Configuration Compare
CAN Configuration Compare :material-information-outline:{ title="Minimum Version: 8.86.2.4" } lets you inspect two `.clc` CAN configurations side‑by‑side and optionally merge any differences back into the active document before downloading the result to an ECU.
1. Launch System Monitor
- Ensure the project you want to update has a CAN configuration document open in System Monitor (this becomes the **Main** side of the dialog).
2. Choose **Logging > CAN Configuration Compare** from the menu or press **Ctrl+F9**. System Monitor briefly locks communications and runs offline while the dialog is open to prevent background threads from modifying writable CAN parameters.
- The dialog stays on top until you press **Save** (applies changes) or **Cancel** (closes without modifying the active CAN configuration).
{ width="200" }
!!! info "Reading the comparison"
- The dialog is divided into two mirrored panes. The **Main** pane (left) is read-only and always reflects the currently active CAN configuration; its text box shows the full path of that document.
- The **Compare** pane (right) starts empty. Click the **`...`** button to open any `.clc` file. You can only open documents that use the CAN configuration template, and only the first CAN configuration inside that file is used for comparison.
- The **Compare** text box and label update with the loaded file name. Press **Unload** to drop the comparison document, empty the right tree, and clear the copy buttons so you can start over with another file.
- Check **Show Differences Only** to hide every node that matches (green items), leaving only the red nodes that carry mismatches. Unchecking the box reruns the comparison to reveal the full structure again.
- Both trees use color‑coding: **green** nodes match, while **red** nodes differ or are unmatched in the opposite tree. The parent branches also turn red when any child is different.
- Clicking a node on either side automatically selects its best match on the other tree and opens the detail panel below it. Each side hosts a dedicated detail mini-dialog, so you can inspect either bus-level, buffer-level, message-level, or parameter-level properties without leaving the window.
- **Bus detail panel** shows name, buffer count, global mask, link speed, controller ID, parameter address, and block size.
- **Buffer detail panel** shows the buffer name, receive mask, rate, number of messages, and the list order of those messages.
- **Message detail panel** lists the description, standard/frame flag, buffer assignment, message length, parameter count, multiplexing attributes, byte order, start bit, bit length, and the number of values.
- **Parameter detail panel** surfaces the parameter name, start bit, bit length, signed/unsigned, byte order, scaling gain/offset, multiplexer ID/value, and mask.
- The detail panels highlight only the fields that differ.
- Right-clicking on the Compare tree pops up a context menu that mirrors the `<`/`<<` buttons and shows tooltip text (e.g., “Merge 'MainBus' details”).
{ width="500" }
3. Merging differences
- The `<` button (Copy Selected) copies the currently highlighted Compare node into the Main tree. It works for buses, buffers, messages, and parameters. The command overwrites the selected node, and—when appropriate—adds missing messages or parameters to the Main configuration and preserves existing parameter objects.
- The `<<` button (Copy All) is designed for whole branches. When you select a bus or message and press `<<`, the dialog copies that node plus every child buffer/message/parameter so the entire subtree matches the Compare side.
- Both buttons remain disabled until you select a **red** node in the Compare tree, and the selection also enables the detail panels for a quick sanity check.
- After any merge, the dialog reruns the comparison, collapses/expands the tree to refresh the view, and re-evaluates the `Show Differences Only` filter.
4. When you are happy with the merged result, click **Save** (default button) to close the dialog with `IDOK`.
- If System Monitor is connected to an ECU and the ECU is not running in read-only mode, you will see the prompt: _“Do you want to download a new logging configuration to the ECU?”_ Confirming that prompt pushes the merged configuration down to the ECU.
- If the ECU connection is not available or CAN-only behavior is enabled, System Monitor exports the merged CAN messages instead.
- Press **Cancel** to close the dialog without persisting any merges. The temporary configuration copy is discarded, and the active CAN configuration remains untouched.
!!! tip
- Always load the correct base CAN configuration before opening the compare dialog—the left tree is read-only and cannot be swapped inside the dialog.
- Unload a compare file before selecting a different one to avoid keeping multiple documents open at the same time.
- You can toggle **Show Differences Only** at any time to keep the trees focused on mismatches; unchecking the box reruns the comparison and shows every node again.
- The Compare tree tries to match nodes by name or ID, so renamed buses/messages may still appear as differences even when the parameters inside line up.
- Right-click on the Compare side to see context-aware merge descriptions and to invoke the same `<`/`<<` actions without moving your mouse to the buttons.
- After closing the dialog with Save, use the standard System Monitor workflow to save the project and to revisit any downstream logging or download steps.
## CAN FD
??? "What Is CAN FD?"
CAN FD (Controller Area Network with Flexible Data-rate) is an extension of the classic CAN protocol that provides:
- **Larger payloads** — up to 64 bytes per message frame (classic CAN is limited to 8 bytes).
- **Higher data-phase bit rates** — a separate, faster bit rate for the data portion of the frame while keeping the arbitration phase at the standard speed.
- **Defined frame sizes** — CAN FD uses discrete data length values: 0–8, 12, 16, 20, 24, 32, 48, and 64 bytes.
### How to Configure CAN FD
**Prerequisites**
- A hardware controller that supports CAN FD (the controller's PGV/description file must declare CAN FD support and available data speeds).
**Steps**
1. **Connect** to a CAN-FD-capable unit. The CAN Bus configuration page will show the **"CAN-FD Supported"** label and the **Data Speed** dropdown.
{ width="200" }
2. **Set the Data Speed** — Select the desired data-phase bit rate from the **Data Speed** dropdown on the CAN Bus configuration page. The **Link Speed** (arbitration speed) is configured as before.
3. **Create or edit a CAN message** — On the CAN Message configuration page, tick the **CAN FD** checkbox to mark the message as a CAN FD frame.
{ width="200" }
4. **Set the message length** — Use the length spinner to choose a valid CAN FD data length (up to 64 bytes). The control will snap to the nearest valid CAN FD length.
5. **Add parameters** — Configure parameters as usual. Start bit values can now range from 0 to 511 for CAN FD messages.
6. **Review the layout** — Use the **Parameter Layout** button to open the layout grid and verify parameter placement across the full CAN FD frame.
7. **Download the configuration** — Download to the hardware unit as usual. The system automatically selects the correct parameter structure format (V1 for classic CAN, V2 for CAN FD) based on the controller capability.
### Valid CAN FD Data Lengths
CAN FD does not support arbitrary data lengths above 8 bytes. The following data lengths are valid:
| Bytes | Bits |
|-------|------|
| 0–8 | 0–64 |
| 12 | 96 |
| 16 | 128 |
| 20 | 160 |
| 24 | 192 |
| 32 | 256 |
| 48 | 384 |
| 64 | 512 |
The message length control in System Monitor enforces these values automatically.
---
# Overview
Configure and calibrate sensors in TAGtronic systems to convert physical properties into electrical signals for logging and analysis.
System Monitor has the following facilities to configure the way that Sensors are used:
- Sensors & Actuators - Used to apply Calibration data to sensors, enable/disable individual sensors and enter values for sensor constants. Used on sensors and actuators defined in the Program Version.
- External Inputs Configuration - Used to configure sensor inputs and apply Calibration data to sensors connected to the ECU. Used on sensors that are not defined in the Program Version. Also used to configure systems using communication links such as TAG Sensor Bus or CAN.
- Sensor Calibration Tool - Used to view and edit sensor calibration curves.
## Configuration Tools
### [Sensors & Actuators](./sensors-and-actuators.md)
For Program Version defined sensors:
- Apply calibrations
- Enable/disable sensors
- Assign serial numbers
- Set sensor constants
!!! note
Requires associated Sensor Set file
### [External Inputs Configuration](./external.md)
For non-Program Version sensors:
- Set up input sources and buses
- Configure and assign sensors
- Apply calibrations
- Supports drag-and-drop
## [Software Calibration](./software-calibrated-sensors.md)
TAGtronic systems use lookup tables for software calibration:
- `.dat` files contain calibration data
- Convert to `.bcf` using `Sbinary.exe`
- Store in Multi-Application Base root
!!! important
Sbinary must be configured in Advanced Settings
---
# External Configuration
The External Inputs Configuration Tool allows sensor inputs to be configured and calibration data to be applied to sensors connected to the ECU.
External Inputs Configuration operates on sensors that are not defined in the Program Version. Use Sensors & Actuators Tool for sensors and actuators that are defined in the Program Version. It is also used to configure systems using communication links such as TAG Sensor Bus or CAN.
To open the External Inputs Configuration Tool, select: **Sensors > External Inputs Configuration**.
!!! note
If this menu item is not available, select: **File > New** and then select **External Inputs Config** from the list of documents in the File New dialog box. External Inputs Configuration is only available if the relevant Customer Base has permission, as set in Customer Base Advanced Settings.
## Prerequisites
To change the External Inputs configuration in the ECU, you must download it from System Monitor. To modify an existing External Inputs configuration in the ECU, that configuration must first be uploaded to System Monitor.
The External Inputs parameters are shown in the Parameter Explorer. The **Parameter Properties - Sensor** tab shows information about the external inputs configuration for the selected sensor.
## Configuration Steps
To configure a DATALab system repeat these steps as required until the system is fully configured. The configuration can then be sent to the ECU and/or saved as a file.
### Select An Input Source
The left-hand side of the dialog box displays the sensor inputs to the unit. The type of unit is shown at the top with the input sources listed below it. System Monitor only shows the input sources that are available for the unit.

TAGtronic data loggers and ECUs can accept input from the following sources:
- **TAG Sensor Bus** - The communication link in the DATALab system.
- **CAN Link** - A serial data communication protocol.
- **Unit Sensors** - Sensors which are connected directly to the unit.
### Select a Bus
To select a bus:
1. Expand the **TAG Sensor Bus** item by clicking the expand icon.
2. Click on the **Bus** (or Loom) to configure.
3. Select the type of Sensor Node to configure by selecting **None**, **SN-6**, or **SN-32**.
4. Click **Apply** to accept the configuration.
5. The tree structure expands to allow you to select a Node.

### Select a Node
After you have selected a Bus, the tree structure expands to allow a Node to be selected.

To select a node:
1. Select the **Node** that you want to configure in the left-hand pane.
2. Enter the address of the Node in the **Serial Number** text box in the Node panel. The address is set by hardware and is printed on a label on the case of the sensor node.
> **Caution:** An address of 0 means that the node is not connected and cannot be configured. If you change the address of a configured node to 0, all its settings are lost without warning.
3. Select the type of Sensor Node from the **Type** drop-down list. There is only one type of SN-6.
4. Click **Apply** to accept the configuration.
The node in the tree structure expands and the **Timer Resolution** boxes appear.
5. Select the **Timer Resolution** from the drop-down lists. Timer resolution is used for pulsed speed sensors. Two timer resolutions are available. The range is from 400 nSecs to 51.2 µSecs, doubling with each step. The default is 400 nSecs.
### Add a Sensor
After you have selected a Node, sensors can be added to it.
The tree structure shows the configuration of sensor inputs to the unit.

To add a sensor to the system:
1. Expand the **Node** where you want to add the sensor by clicking the expand icon. If you want to connect directly to the unit, expand **Unit Sensors**.
2. Select the sensor location by clicking on it.
3. Select the **Type** of sensor from the **Type** drop-down list. The list is taken from the Sensors.ini file. Some locations are only suitable for particular types of sensor. The list only shows those sensors which are suitable for the location. The **Harness** text box shows the pin and socket to which the sensor must be connected.
> **Note:** Speed sensors (Hall effect or Inductive) require further scaling. For these sensors, the **Advanced** button is enabled. Click this to open the **Revs Scaling** dialog box.
4. Select the serial number of the sensor from the **Serial No.** list. For Software Calibrated Sensors, this associates the appropriate calibration data with the sensor. The calibration data is shown graphically. For other sensors, select zero. If no serial numbers are available, the box is grey and a serial number of zero is assumed.
> **Note:** A serial number can also be assigned to a sensor by Sensors & Actuators. This is not linked to the External Inputs Configuration, so you will not be prevented from using the serial number more than once.
5. Enter the **Name** to be used for the Measurement Parameter generated by the sensor in the **Parameter** text box. The **Identifier** is fixed by the location of the sensor in the DATALab configuration and cannot be edited.
6. Enter the **Description** to be used for the Measurement Parameter generated by the sensor in the **Description** text box.
7. Click **Properties** to open the **Parameter Properties** dialog box. The Parameter Properties are the same as for a Measurement Parameter but more attributes can be edited.
8. To add another sensor, click on the appropriate location on the tree diagram and repeat from step 3.
> **Note:** To select a different Node or Bus to configure, click on the appropriate location on the tree diagram.
9. When you have finished adding and configuring sensors, click **OK**.
The changes made are accepted and a Measurement Parameter is added to the External Inputs Parameters Group for each newly added sensor (the Group is created if it doesn't already exist).
A message box opens asking whether to download the configuration. If you select **No**, the configuration is retained in the project and may be saved or downloaded at another time using the **External Inputs Download** command on the Logging Menu.
## Speed Sensor Scaling
The **Revs Scaling** dialog box is opened for Inductive and Hall Effect sensor types by clicking **Advanced** on the **External Inputs Configuration** dialog box when a Sensor is being added.
Speed sensors provide a pulse signal when they sense the movement of a piece of ferrous metal. This signal is usually caused by the rotation of a toothed wheel, and the output of the sensor is converted to a road speed or revolution value.
Use the **Revs Scaling** dialog box to configure the conversion of the sensor output to give the desired parameter.

### Configuration Options
**Output Units** - Select the units that you want the sensor output scaled to:
- **MPH** - Road speed in miles per hour (default)
- **KPH** - Road speed in kilometres per hour
- **RPM** - Engine speed in revolutions per minute
- **Hz** - Frequency in hertz (cycles per second)
- **µSecs** - Time interval in microseconds
**Wheel Radius/Circumference** - For MPH and KPH scaling only. Enter the size of the wheel in metres. Entering a value in one field automatically recalculates the other. For example, the circumference value is updated if a value for a radius is entered. The Radius value must be non-zero.
**No. of Teeth** - Enter the number of teeth on the wheel. Automatically set to 1 if the Output Units are Hz and 0 if the units are µSecs. For MPH, KPH, or RPM, the value must be non-zero.
**Edge Trigger** - Choose which edge of the sensor signal will trigger the timing pulse:
- **Positive Edge** - The trigger detects a rising voltage (default)
- **Negative Edge** - The trigger detects a falling voltage
**Timer** - Select the Timer from the drop-down list. The default is Timer 0. The Timer Resolution is set when you [Select a Node](#).
**Max. Speed** - A nominal maximum speed can be entered. This is optional.
**Max. Speed Accuracy / Low Speed Cut Off** - If a Max. Speed has been entered, System Monitor calculates the Max. Speed Accuracy and Low Speed Cut Off from the Timer Resolution and the Number of Teeth. These are read-only items.
## Input Signal Configuration Tool
To open the Input Signal Configuration Tool, select: **Logging > Input Signal Configuration**.

The Input Signal Configuration Tool provides the ability to configure analogue and digital input signals from MESL units. This tool enables you to:
- Manually configure analogue and digital input signals
- Sample the signal/sensor's transfer function
- Export an input configuration to file
- Import an input configuration from file
- Recalculate the offset
- Obtain an overview of how all inputs are configured
- Manage the Input Scaling regime
- Manage the Hardware and Filter configuration
**Scaling Methods**
The tool supports the following scaling methods:
- Interpolation Table
- Look-up Table
- Gain and Offset
- High and Low Sample Points
- Extrapolation
- Rotational
- Wheel Speed (Metric)
- Wheel Speed (US)
When you click the **OK** button in the dialog, all modifications are accepted and written to the data version file, which must be downloaded to the unit for the modifications to be applied.
If you have re-sampled one or more signals, the logging configuration file containing these modifications must also be downloaded to the unit. The status of both files (data version and remote logging configuration) can be viewed in the ECU Bar Display.
Within the System Monitor Parameter Explorer, all scaled measurement parameters are grouped in a new top-level menu called **Input Signals**. These parameters also appear in an **Input Signals** group within ATLAS logged data.
**Context Menu**
By right-clicking the explorer tree on either a group node or an individual input signal, you are given the following options:
- **Import Signal** - Exports the selected signal properties to a CSV file.
- **Export Signal** - Imports the selected signal properties from a CSV file.
- **Clear Signal** - Clears the selected signal, resetting all values to 0.
If you right-click the group header node (for example, **AN01-AN12(400kSPS)**), the same context menu appears; however, the selected action will be performed for all signals in that group.
---
# Software Calibrated Sensors
The output of many sensors is inherently non-linear (the output is not proportional to the input). A linear output is often achieved by limiting the sensor range and adding complex compensation circuitry. This reduces sensor usefulness and increases cost.
An alternative is to accept the non-linear output and use the ECU's computing power to compensate by referring to a lookup table. This is known as Software Calibration and is supported by all TAGtronic control systems and sensors. This method lets you use simple, robust, and relatively low-cost sensors while obtaining the best possible accuracy.
## Calibration Files
When the project is created, the Sensor PRM file is read and the latest ASCII (.dat) Sensor Calibration data is converted to a binary calibration file by Sbinary.exe. Sbinary is a conversion utility that runs in DOS. The name and location of the Sensor.prm file is defined in the Advanced Settings dialog box.
**Features**
- The binary calibration file is stored in the Multi-Application Base root directory and has the same name as the .prm file but with the .bcf extension.
- When data is downloaded to the ECU, a sensor configuration created from the .bcf file is also downloaded.
- If the .prm file or any .dat files are newer than the most recent .bcf file, Sbinary runs to update the .bcf file when Sensors & Actuators is opened.
- **Note:** You can also run Sbinary.exe using the Force Prm Check command for the Sensors & Actuators Tool.
- Sbinary is supplied with sensor calibration data obtained from McLaren Applied. To install Sbinary, run Install.bat from the calibration data disk.
- **Note:** Ensure the Location of sensor calibration files in Advanced Settings matches the Sbinary installation location.
- Sbinary requires the following file structure:
- Sbinary.exe must be in the same directory as the Sensor PRM file.
- You must have write access to the directory containing Sbinary.exe to allow it to create temporary files.
- The .dat calibration files are placed in subdirectories below the directory containing Sbinary.exe and the Sensor PRM file.
- The names of .dat files and their containing directories must conform to DOS 8-character naming rules. Long names must not be used.
## Sensor Calibration Tool
The Sensor Calibration tool allows sensor calibration curves to be viewed and edited. To open the Sensor Calibration dialog, select: **Sensors > Live Calibration**. If the ECU is online, the Select Live Calibration Parameter dialog appears first. If not required, click **Cancel** to open the Sensor Calibration dialog.
The dialog box has three panes:
- **Left pane:** Contains a list of sensors from the .prm file. Only sensors with calibration data are shown. Click `+` to show serial numbers of individual sensor types. If `+` is unavailable, the default calibration is used. The selected Sensor Type and Sensor Number also appear in the text boxes at the bottom.
- **Centre pane:** Shows the calibration data for the selected sensor from the .dat file:
- **Voltage:** The sensor output in volts. Only 0-5 volt output sensors are supported; other sensors require an interface amplifier.
- **Value:** The quantity in engineering units associated with the sensor output. For example, a pressure sensor with a 0-10 bar range may have a value of 10 at 5 volts, 5 at 2.5 volts, and 0 at 0 volts.
- **Right pane:** Displays calibration data as a graph. The graph also appears for selected sensors in External Inputs - Configuration.
## Live Calibration
Live Calibration allows you to calibrate a sensor using real input.
1. Set up a connection to the sensor using External Inputs Configuration. Ensure the configuration is downloaded to the ECU.
2. Prepare to apply known engineering loads to the sensor.
3. Put the ECU online.
4. Select: **Sensors > Live Calibration** to open the Select Live Calibration Parameter dialog.
5. Select the parameter associated with the sensor you want to calibrate.
6. Click **OK** to open the Sensor Calibration dialog.
7. On the Sensor Calibration dialog, click **Live Cal** to start the calibration wizard. The current voltage output from the sensor appears in the Voltage text box and under Breakpoint in the centre pane.
8. In the Engineering text box, enter the value in engineering units corresponding to the current load on the sensor. Click **Next**.
9. Change the sensor load so the Voltage value increases and repeat step 8.
10. Continue until you have entered all calibration points. Click **Finish** to stop the calibration.
11. Click **OK** to accept the calibration. The .dat file associated with the sensor is updated.
---
# Sensors and Actuators
Sensors & Actuators allows you to apply calibration data to sensors, enable and disable individual sensors, and enter values for sensor constants. It operates on sensors and actuators defined in the Program Version.
!!! note
- Sensors & Actuators is available only if the relevant Customer Base has permission (set in Customer Base Advanced Settings).
- Use External Inputs Configuration for sensors that are not defined in the Program Version.
## Sensor Sets
Sensor sets are files containing the sensor and actuator data. They are stored in the `\SenSets\` sub-directory of the Multi-Application Base.
When a Sensor Set is opened (File > Open) the Sensors & Actuators dialog box for the Sensor set is opened and the set is associated with the Project.
### Creating new Sensor Sets
- To create a new sensor set select: File > New.
The Sensor Set Upload command automatically creates a new sensor set file if there is not already one associated with the Project.
!!! note
The new file only contains sensor data for the Active Applications. Ensure that you make the appropriate applications active before creating a new sensor set file.
Default name for a new sensor set:
- `XXXXXnnn.set`, where:
- `XXXXX` — first five characters of the Application Name, or `Calib` if more than one application is active.
- `nnn` — a three-digit hex number, starting with `001`, incremented whenever a new sensor set file is saved.
### Saving Sensor Sets
- If changes are made to the sensor data (including uploading from the ECU), you will be prompted to save the sensor set when you close the Sensors & Actuators dialog box.
- To save under a different name: File > Save As.
!!! note
To see which Sensor Set files are in use and to upload or download files, use the Unit Status command in the Tools menu.
## Sensors & Actuators dialog box
The dialog box is opened by one of the following actions:
- Opening an existing Sensor Set (File > Open or Sensors > Open Sensor Set).
- Uploading an existing Sensor Set (Sensors > Sensor Set Upload).
- Creating a new Sensor.Set file (File > New).
The dialog box is opened for a single Sensor set. The Sensor.Set file name is shown in the title bar.
A Sensor set links each sensor and actuator connected to an ECU to its calibration data. The `Sensors.ini` file lists the sensors and actuators connected to the ECU and defines on which tab they are placed in the Sensors & Actuators dialog box. Tab allocation is arbitrary and is not linked to the Groups described in Names, Descriptions & Groups.
Each tab has the following columns:
- Name — allocated to the sensor by the `Sensors.ini` file.
Note: This name is not linked to the Name or Description of the Measurement Parameter that the sensor generates.
- Type — allocated to the sensor by the `Sensors.ini` file. More than one sensor can be of the same Type.
Note: This Type is not the same as the Type described in Names, Descriptions & Groups.
- Serial — each TAGtronic sensor is unique and individually calibrated. To ensure correct calibration data is used, the serial number in this column must match the serial number of the device.
- If the serial number is shown as `0`, a default set of calibration data is used.
- If the serial number is shown as ``, System Monitor was unable to find a default set of calibration data. If there are also no numbers in the drop-down list, the `.dat` file was most likely not found.
- Date — the date that the sensor type was calibrated as defined in the `.dat` file.
- Status — general comment about the sensor (for example, “Passed Inspection”).

!!! tip
- The Notes text area allows up to 238 characters to be entered, which are stored in the ECU. (If Unicode ASCII format is used, only 119 characters may be entered.)
- To print the information in the dialog box: File > Print while the box has focus.
## Sensors & Actuators — Serial Numbers
Assign calibration data to sensors or actuators:
1. Open the Sensors & Actuators dialog box.
2. Select the tab on which the device is listed.
3. Select the row for the device. If you select more than one row (using CTRL or SHIFT), you can automatically assign sequential serial numbers.
4. Click the cell in the Serial column for that row to open a text box. To open the text box with the keyboard, type any number. To assign sequential serial numbers to multiple devices, type any number to open a text box for the top row of the selection.
5. Select a serial number from the drop-down list. It is recommended to use the drop-down list rather than entering a serial number manually, as it only includes valid numbers for calibrated sensors. Uncalibrated sensors may be given any serial number.
- When the text box is open, use the UP and DOWN cursor keys to select a number.
6. Accept the selected serial number by pressing ENTER or double-clicking the number. To leave the row without changing the value, press ESC or click another row.
- If more than one row is selected: the first item is assigned the chosen serial number and each subsequent item receives a number one higher (if available). If a serial number is not available, `0` is assigned to that device. If `0` is entered for the first device, all selected devices are assigned `0`.
- A serial number can only be assigned to one sensor of a given Type. If you choose a serial number that is already assigned to another sensor, the following warning is displayed:
- `image\S_A_Serial_Warning.gif`
- Select YES to assign the serial number to the newly selected sensor; the previously assigned sensor will be assigned a serial number of `0`.
- Select NO to assign a serial number of `0` to the newly selected sensor; the previously assigned sensor retains its number.
> **Note:**
> - A serial number can also be assigned by the External Inputs Configuration. This is not linked to Sensors & Actuators, so you will not be prevented from using the serial number more than once.
> - Injectors have a further Class characteristic. The Class is associated with the serial number. System Monitor ensures that injectors of the same Type also have the same Class.
7. Repeat from step 1 until all allocations are complete.
8. Save the file.
9. Use Download on the Sensors & Actuators sub-menu of the Tools menu to send the changes to the ECU.
## Sensor and Actuator Constants
Some sensor types require one or more constant values to be entered to complete their calibration. Constants can be placed on any tab in the Sensors & Actuators dialog box and may be mixed with sensor descriptions. For clarity, constants are usually placed on a separate tab.
Assign a value to a constant:
1. Select the row for the constant.
2. Enter the value. A text box opens automatically. The Edit Context Menu becomes available.
3. To accept the value, click another row or press ENTER. To leave the row without changing the value, press ESC.
The data on the Constants tab is part of the Sensor set data. It is sent to, and obtained from, the ECU with the sensor set data.
## Enabling and Disabling Sensors and Actuators
The Enable/Disable Sensors dialog box lists all Sensors and Actuators which can be enabled and disabled by System Monitor. The `Sensor Enable/Disable.ini` file defines these sensors and actuators; they do not have to be the same as those listed in the Sensors file.

To open the dialog box: Sensors > Enable/Disable.
- The list can be sorted by Name or Group. Names and Groups are taken from the Enable/Disable file and are not the same as the names and groups in the Sensors & Actuators dialog box.
- Enable/Disable Sensors only operates on a connected ECU and its settings are not saved in the Sensor Set files. When an ECU is connected, the State column shows whether each sensor or actuator is enabled or disabled.
Change the state of a sensor:
1. Select the row for the device by clicking or by using the UP and DOWN cursor keys. To select multiple rows, use CTRL or SHIFT in conjunction with the mouse or the Space Bar.
2. Right-click and select Enable or Disable from the Context menu.
- A message is sent to the ECU to enable or disable the sensor. When the change has been made, the State column updates to confirm the new status.
!!! note
Pressing ENTER toggles the status of the selected sensors between Enable and Disable without using the Context menu.
- Disabling a sensor makes a change in the ECU memory that prevents the output of the sensor from being used in any way. The logging of a sensor can be switched off without disabling it if required.
---
# Obtaining Sensor Calibration Data
Sensors and actuators supplied by Motion Applied are tested at multiple points in their operating range to produce a calibration table. This table is saved as an ASCII format file with the `.dat` extension and is shipped with the sensor.
!!! warning
- Do not amend the sensor calibration database while System Monitor is running
- Do not edit the contents of `.dat` files
You can also obtain calibration information by connecting to the Motion Applied network using the Get Sensor Data Utility.
## Get Sensor Data Utility
### Access Requirements
To obtain sensor calibration data from the Motion Applied network:
1. Apply for a remote login account
2. You'll receive setup instructions (WPD.TWPD0176) for Dial-up Networking via modem
3. You'll be allocated a username and initial password (which you can change)
### Network Access
You'll have access to:
```
TAGSVR1\SYS:\HOME\username\
```
This path maps to the `F:` drive (if available). Access is restricted to the network supervisor, whether within or outside Motion Applied.
The `gs` (Get Sensor Data) utility retrieves TAG sensor calibration data on a read-only basis and cannot modify database master files.
## Using the Get Sensor Utility
The `gs` utility is located at:
```
TAGSVR1\SYS:\HOME\username\FROMTAG\SENSOR
```
1. Run `gs` to open a DOS window with the prompt:
```
Enter Order Code [TYPE QUIT TO EXIT]:
```
2. Enter the full order code (include leading `o` and all spaces; case-insensitive):
```
o 030 330 001 001
```
3. Confirm the sensor type when prompted:
```
The order code you have entered corresponds to: ––– 250 bar Pressure Sensor ––– is this correct? [Y/N]
```
Enter `Y` to accept.
4. Enter the quantity of sensors needed. Precede with `R` for automatic sequential serial numbering.
5. Enter the serial number for each sensor (e.g., `160`).
6. The utility retrieves data and appends it to `SENSOR.DAT` in the current directory. For amplified pressure sensors, a second file `SENSOR2.DAT` is created.
7. Repeat steps 4-6 for each sensor type required.
8. Type `QUIT` at the prompt to exit. The filename and size are displayed.
9. Transfer the `OUTPUT` subdirectory contents to your computer and copy to CD-ROM.
!!! note
Exit at any time by entering `quit` or `QUIT`. If an order code or serial number isn't recognized, you'll be prompted to re-enter it.
---
# Overview
Tuning is the process of optimising vehicle performance by adjusting the values of **Editable Parameters** within the ECU (Engine Control Unit). These adjustments can be made in several modes depending on the setup and workflow.
## Tuning Modes
### Off-line Tuning
- Changes are saved in a **New Data Version**.
- The ECU does **not** need to be connected during editing.
- Changes are downloaded to the ECU at a later time.
### On-line Tuning
- The ECU is connected to **System Monitor** during editing.
- Changes can be sent immediately using **Live Tune** or on demand.
### Automatic Tuning
- System Monitor can operate with an automatic **Testbed**.
- Supports the **AVL PUMA** protocol for unattended engine tuning.
## [Adjustment Board](../hardware/index.md/#adjustment-board)
To simplify value adjustments, an **Adjustment Board** can be connected to System Monitor. This allows physical control over parameter changes using potentiometers.
---
# Editable Parameters
Editable Parameters are values within the ECU that can be modified to optimise engine performance. These parameters are defined in the ASAP file by the ECU manufacturer and may be edited depending on permissions.
## Scalar Parameters
A **Scalar** parameter holds a single constant value.

**Scalar Edit Window**
- Displays multiple Scalar parameters in rows.
- Columns include:
- **Name/Description**: Configurable via Window Properties.
- **Value**: Editable; colour changes on acceptance (default red/blue).
- **Trend Arrow**: Indicates increase or decrease.
- **Units**: Shown if Engineering format is selected.
- **Address**: Shown if Raw Hex or Binary format is selected.
!!! note
Scalar parameters can also be edited in a Grid window.
## 1-Axis Maps
A **1-Axis Map** is a one-dimensional lookup table. The output value depends on the selected **Breakpoint** on the axis.
**Features**
- Active cell outlined in black when ECU is online.
- Colour changes on value acceptance.
- Optional **String Bar** displays associated string values.
- **Edit Bar** shows Breakpoint and Output values.
- Display options: Engineering, Raw Hex, or Address.
- Graphical format available.
- Orientation can be rotated via System Menu.
### Multiple Parameters
- A 1-Axis Map window can include multiple parameters sharing a common axis.
- Parameters not sharing the axis are excluded with a warning.
- Orientation can be toggled to display parameters in columns.

## 2-Axis Maps
A **2-Axis Map** is a two-dimensional lookup table. Output depends on selected Breakpoints on both axes.

**Features**
- Output and Breakpoint values are editable; colour changes on acceptance (default red/blue).
- Active cell outlined in black when ECU is online.
- Grid structure includes:
- X-axis identifier name row
- X-axis Breakpoint values row
- Y-axis rows with Output values and Y-axis identifier/Breakpoints
- Optional **String Bar** displays associated string values.
- **Edit Bar** shows X-axis Breakpoint, Y-axis Breakpoint, and selected cell values; non-editable boxes display Index Parameters and Output value when online.
- Window and axis titles can display Name, Description, or both (configured in Window Properties).
- Display options: Engineering, Raw Hex, or Address format.
- Graphical format available.
- Live Tune Overview minimizes empty cells for better visibility.
- Orientation can be exchanged via System Menu.
- Appearance controls available in Window Properties Display tab.
## Arrays
An **Array** is a one-dimensional ordered group of values selected by an index.

**Features**
- Only one Array parameter per window.
- Editable values with colour change on acceptance.
- Grid layout includes:
- Output values (rows/columns configurable)
- Index row
- Optional **String Bar** and **Edit Bar**
- Window title can show Name, Description, or both
## Strings
A **String** parameter outputs text rather than numerical values.

**Features**
- Multiple String parameters can be displayed.
- Editable within defined length (set in ASAP file).
- Columns include:
- **Name/Description**
- **Value**
- Column widths and sorting are configurable.
- Can be associated with Maps or Arrays.
!!! note
- Editable Parameters must be part of an **Active Application** and not marked as **Read Only**.
- Editing permissions are controlled by the ASAP file.
---
# Changing Values
Each Parameter is defined in the ASAP file by the ECU manufacturer. The ASAP file either permits or prevents System Monitor from changing the values of an Editable Parameter. If the Editable Parameter values are prevented from being changed, the edit boxes are disabled.
You can only change values of parameters in an Application that is Active and not Read Only.
When a value is changed and accepted, its colour changes to the Greater than / Less than colour (default red/blue) as appropriate. These colours are defined in the Display tab of the Window Properties dialog box. The Scalar Display uses arrow icons to show the direction of value changes.
## Editing options
- Edit commands are available on the Edit Context Menu.
- Use the Maths Bar to carry out mathematical operations on the selected value or values.
- The Breakpoint Values of 1-Axis and 2-Axis Maps can be edited if required.
- To restore values to their original values, select: Edit > Restore or use the Windows Context menu.
## Parameter Edit Mode
A single value of an Editable Parameter can be displayed with Edit Mode either On or Off. Entering a new value turns Edit Mode on and the value is overwritten. Edit Mode is turned on when a single cell is selected using the mouse.

**Edit Mode On**
- Only the text is highlighted.
- Only one cell can be selected.
- The Edit Context Menu is available.
- If Copy is selected, only the value is sent to the clipboard. Paste and Paste Special can only paste the value as text.
To turn Edit Mode Off, press ESC or ENTER.
**Edit Mode Off**
- The whole cell (or row in Scalar or String Windows) is highlighted.
- Blocks of cells can be selected.
- The Windows Context Menu is available.
- If Copy is selected, the value plus a reference to the original parameter is copied to the clipboard. All Paste and Paste Special options can be used.
Pressing a cursor key while the cell is in Edit mode selects the next cell in the direction of the arrow with Edit Mode off.
If multiple values are selected, Edit mode is always off. Editing a number overwrites the first (top left) of the multiple values.
**Changing Parameter Values by Mouse**
Click on the value to be changed and enter a new number to overwrite the existing value. Alternatively, select the appropriate text box in the Edit Bar and enter a new value.
To select more than one value do one of the following:
- Click and Drag to select a continuous rectangle of values. (If the value is in Edit Mode press ESC before dragging)
- Click on a corner of the rectangle of values you want to select. Hold down the SHIFT key and click on the opposite corner
- To select non-continuous values, hold down the CTRL key while clicking on values. (Non-continuous blocks of values cannot be copied.)
If multiple values are selected, entering a value overwrites the first (top left) of the multiple values.
The Maths Bar operates on all the selected values.
!!! note
It is also possible to change values by dragging with a mouse in a Graphical Map.
**Changing Parameter Values by Keyboard**
Select the value to be changed using the cursor keys and enter a new number to overwrite the existing value. Alternatively, use the TAB key to cycle through the edit boxes in the Edit Bar.
2 axis Map Edit Bar
To select more than one value:
- Using the cursor keys, select a cell at a corner of the rectangle of values you want to select. Hold down the SHIFT key and select a cell at the opposite corner.
- To select non-continuous values, hold down the CTRL key while using the cursor keys, press the SPACE bar to include values. (Non-continuous blocks of values cannot be copied.)
If multiple values are selected, entering a new value overwrites the first (top left) of the multiple values. The Maths Bar operates on all the selected values.
## Value Limit Warning
Each Parameter has an upper and lower limit that is set in the ASAP file. The limits can be viewed in the Conversion tab of the Parameter Properties dialog box.

If a value is changed so that it is outside the limits, the Limit Warning dialog box opens.
The Upper and Lower limits are shown in the Limits panel. If the Parameter Properties can be edited, the Upper and Lower limits text boxes are editable and the limits can be changed.
In the Value panel:
- Entered — Shows the out-of-range number that was entered. If you edit this box to a number that is within range, the new number is accepted when you click OK.
- Adjusted — System Monitor automatically suggests a new number, which is the value of the limit nearest to the out-of-range number that was entered. If you click OK without editing a number in the Entered text box, the Adjusted number is accepted.
Buttons:
- OK — Replaces the selected value with the value in the Entered text box provided it is within limits.
- If the value in the Entered text box is not within limits, the selected value is replaced by the value in the Adjusted text box.
- If multiple values are being changed, steps through the values one at a time.
- OK to All — Available for multiple values only. As OK but applies the same change to all the values.
- Cancel — The change is ignored and the original value is restored.
## Changing Breakpoint Values
### Mouse operation
To select an X-axis Breakpoint click on the column header. To select a Y-axis Breakpoint click on the row. When a cell is selected, it changes to Edit Mode. Enter a new value to overwrite the existing value.
!!! note
If Orientation is selected in the Window System Menu, the axes are rotated.
Alternatively, click on the appropriate edit box in the Edit Bar. Select the required breakpoint edit box and overwrite the value.
### Keyboard operation
Use the cursor keys to select a cell that uses the breakpoint that you want to change.
Use the TAB key to cycle through the edit boxes in the Edit Bar. The TAB key then returns to the value in the map table.
Select the breakpoint that you want to change and enter a new value to overwrite the existing value.
## Breakpoint Warning
Changing Breakpoint values affects the axis wherever it is used, not just in the current Window. If the axis is used by other Parameters, System Monitor displays a Breakpoint Warning.

To prevent this box from being displayed again, select: Don’t show this Warning again for this Axis.
Click List to display a list of all the Parameters that use the axis that you are editing to help you to determine the effect of the change.
## Breakpoint Monotony
All Breakpoint values must either increase or decrease along the axis. This restriction is called Monotony. The direction of monotony is set in the ASAP file and can be viewed in General tab of the Axis Properties dialog box.
This means that a breakpoint value cannot be higher than the next highest value or lower than the next lowest. If you enter a value that breaks this rule, a warning is shown and the value is not accepted.
Click OK to close the warning.
The new value that was entered is replaced by the original value. Only values that are within the surrounding breakpoint values can be accepted.
---
# Graphical Maps
1-axis and 2-axis maps can be displayed in several graphical formats. Select the view format from the System menu for the Window or step through the options with the View Mode button on the Map Bar.
All Graphical Views can be zoomed. 2‑axis Graphical Views can also be rotated. Breakpoint spacing can be Even or Proportional. Values can be changed in all Graphical Views except Difference View. Values can only be changed in active applications.
## Available Views
### 1-axis Map
- Graphical View – 1 axis
A two‑dimensional graph of Parameter value plotted against Index Value. The display includes a plot for each Parameter in the Window. The name of the currently selected Parameter is displayed at the top of the Window. The trace of the currently selected Parameter is shown bold in the colour selected for Active Map in the Display tab of the Window Properties (Display sheet). Remaining traces use the colour selected for Inactive Map.
- Axis upper and lower values are set in the relevant Conversion dialog boxes (see Parameter Properties – Conversion sheet and Axis Properties – Conversion). Axis subdivisions and labels are generated automatically.
- Breakpoint Spacing can be Even or Proportional.
- You can select all values of the selected parameter with the Select All button on the Map Bar.
- Values can be changed in this view.

### 2-axis Map
- Graphical View – 2 axis
A three‑dimensional graph of Parameter value plotted against two Index Values (X and Y).
- Axis upper and lower values are set in the relevant Conversion dialog boxes (see Parameter Properties – Conversion sheet and Axis Properties – Conversion). Axis subdivisions and labels are generated automatically.
- Breakpoint Spacing can be Even or Proportional.
- Hidden lines are removed. To see values below the surface, use End View or Slice View.
- The 3D view can be rotated and zoomed. Values can be changed in Graphical View.

- Difference View (1‑axis and 2‑axis)
The Difference value is the amount by which the current value in the Edit Buffer differs from the value in the Data Version. Difference View plots the Difference value against the Index Value(s). Values cannot be changed in Difference View.
- Unchanged values are set to zero.
- 1‑axis Difference View: two‑dimensional graph of Difference value plotted against Index Value. Only one Parameter is shown; the name of the currently selected Parameter is shown at the top. The largest difference (positive or negative) is used to set the axis upper and lower values.
- 2‑axis Difference View: three‑dimensional graph of Difference value plotted against two Index Values (X and Y). The upper axis value equals that used in Graphical View – 2 axis; the lower axis value is the same magnitude but negative. The 2‑axis Difference View can be rotated.
- Axis subdivisions and labels are generated automatically. Breakpoint Spacing can be Even or Proportional.
- Both Difference Views can be zoomed.

- End View (2‑axis only)
A two‑dimensional graph of Parameter value plotted against the X Index Value for each Y Index Value. The display includes a plot for each Y Index Value.
- The trace of the currently selected Y Index Value is shown bold in the colour selected for Active Map; other traces use the colour selected for Inactive Map.
- Axis upper and lower values are set in the relevant Conversion dialog boxes. Axis subdivisions and labels are generated automatically.
- Breakpoint Spacing can be Even or Proportional.
- Values can be edited in this view.

- Slice View (2‑axis only, available in Graphical View)
Selected by buttons on the Map Bar.
- Slice X: two‑dimensional graph of Parameter value plotted against the X Index Value for the Y Index breakpoint that includes the selected value. The trace for the selected breakpoint is shown bold in the Active Map colour; traces for higher Y Index values (behind) are shown in the Inactive Map colour.
- Slice Y: two‑dimensional graph of Parameter value plotted against the Y Index Value for the X Index breakpoint that includes the selected value. The trace for the selected breakpoint is shown bold in the Active Map colour; traces for higher X Index values (behind) are shown in the Inactive Map colour.
- Axis upper and lower values are set in the relevant Conversion dialog boxes. Axis subdivisions and labels are generated automatically.
- Breakpoint Spacing can be Even or Proportional.
- These views can be zoomed and their values are editable.#

## Zooming a Graphical view
All Graphical Views can be zoomed using buttons on the Map Bar:
- Zoom in — increases the size of the view by 50%.
- Zoom out — cancels each Zoom In setting sequentially.
When any level of Zoom In is selected, the view is centred on the currently selected value. As soon as a value is selected or moved, the display is redrawn to place the value at the centre (the “landscape” appears to move under the point).

To select a value:
- On a 3D display
- Click on an intersection on the surface; or
- Use the cursor keys to move around the surface.
- On a 2D display
- Click on the trace where it is intersected by a breakpoint; or
- Use the left/right cursor keys to move along the trace and the up/down keys to select a trace.
- For either display
- Switch to Engineering View; select a value using the mouse or keyboard, then return to Graphical View.
!!! tip
Use Alt+G to toggle between Graphical and Engineering views.
The Zoom setting is retained for a Window even if its View mode is changed.
For 2D displays, the vertical axis can be scaled using AutoZoom so that the traces fit the plot area.
## Breakpoint Spacing
All Graphical Views can be shown with Breakpoint Spacing either Even or Proportional using the button on the Map Bar.
- Even Breakpoint Spacing
- Proportional Breakpoint Spacing

## Rotating a Graphical view
The three‑dimensional Graphical View for 2‑axis Maps can be rotated using the Mouse or toolbar buttons:
- Toolbar buttons — four buttons rotate the display left/right or up/down in 10° increments.
- Mouse — click anywhere on the Map window (take care not to select a value) and drag the cursor; the front of the display follows the cursor movement.
## Changing Values in a Graphical view
Parameter values can be changed in any Graphical View except Difference View. Values can only be changed in active applications.
!!! note
In a 1‑axis Graphical View you can select all values of the selected parameter with the Select All button on the Map Bar. In all other Graphical Views you can only select one value at a time. To change multiple values.
Steps to change a value in a Graphical View:
1. Select a value:
- On a 3D display: click on an intersection on the surface or use the cursor keys to move around the surface.
- On a 2D display: click on the trace where it is intersected by a breakpoint or use the left/right cursor keys to move along the trace and the up/down keys to select a trace.
- Or switch to Engineering View, select a value using the mouse or keyboard, then return to Graphical View. (Tip: Use Alt+G to toggle between Graphical and Engineering views.)
- The selected value is identified by a black spot. The Breakpoints and Value of the selected point are shown in the Edit Bar.
2. Change the value:
- By mouse — drag the value up or down. If the view is Zoomed In, the display continually redraws to place the value at the centre (the landscape appears to move under the point).
- By keyboard — use the TAB key to cycle through the boxes in the Edit Bar.
3. Enter a new value.
4. Press ENTER to accept the value and redraw the Map.
!!! note
The Maths Bar can be used to change values selected in a Graphical View.
---
# Live Tune
When Live Tune is on, the Edit Buffer and the ECU RAM are kept synchronised — any changes in the Edit Buffer are downloaded to the ECU as soon as they occur.

## Toggling Live Tune
To toggle Live Tune on and off select: ECU > Live Updates.
The status of Live Tune is shown on the Comms Bar.
!!! note
The data changes only affect the ECU RAM. To apply the changes to the vehicle systems, the ECU must be operating from RAM. The type of memory being used by the ECU is selected from the Run from ROM and Run from RAM commands on the ECU Menu.
## If the Data Version Does Not Match
If the Data Version in the Edit Buffer does not match the one in the ECU, the following message is opened for each Application when you start Live Updates. The message presents these options:
- **Sync SM to Unit**
Synchronises the files in System Monitor to match those in the Unit. The specified files are opened in System Monitor, replacing those that are already open. If a file cannot be found, a new file is created using the filename and modification information taken from the unit. Uploads data and places it in the Edit Buffer. Files and data which are the same as already in System Monitor are not uploaded.
- **Reprogram**
Reprograms the ECU then downloads the data changes in the Edit Buffer to the ECU.
- **Force Complete Reprogram**
Forces a Complete Reprogram then downloads the data changes in the Edit Buffer to the ECU.
- **Ignore**
Closes the message box. No changes are made. The download process continues with the next Application.
- **Cancel**
Closes the message box. No changes are made.
# Live Auto Tune
Live Auto Tune assists with manual testbed tuning. It is used in conjunction with Live Tune and the Adjustment Board.
## Definition File and Parameters
The Live Auto Tune Definition File defines a set of Live Auto Tune Parameters. A Live Auto Tune Parameter defines a group of 2‑axis maps and an adjustment parameter. The maps in a Live Auto Tune Parameter share the same axes (for example, throttle position vs engine speed).
Typically, Live Auto Tune Parameters are provided for:
- ignition,
- injection quantity,
- injection end angle, and
- nominal lambda.
Turbocharged engines may have additional parameters for boost pressure and waste gate control.
The Parameter Properties - Live Auto Tune Sheet gives information about the selected Live Auto Tune Parameter.
## Tune Groups and Z Axis
The Live Auto Tune Parameters all have the same number of maps in a set order (e.g. 1, 2, 3). The group of maps at the same level in all the Live Auto Tune Parameters is called a Tune Group. Typically, the Tune Groups are selected for different operating conditions such as “Optimum Power”, “Minimum Consumption” or “Wet Racing”.
The active Tune Group can be selected by:
- the result of a calculation in the ECU,
- the value of a measurement parameter, or
- the driver using a cockpit‑mounted switch.
The index that selects the Tune Group is called the Z axis.
## Operation and Adjustments
As a test is run, the various indexes and controls select a value on one of the maps in each Live Auto Tune Parameter. The Adjustment Parameter is then applied to this value. If the Adjustment Parameter is associated with a control on the Adjustment Board, turning the control applies the adjustment. The way in which the adjustment is applied is defined by the Correction type in the Parameter Properties.
To ensure that a value is selected properly, the Live Auto Tune Parameter defines breakpoint tolerances which override the breakpoint tolerances set for each map (see Parameter Properties - 1‑Axis Map Sheet).
## Saving Adjustments
When you are satisfied with the changes, update the data version in the ECU by selecting: ECU > Save Auto Tune Adjustment.
---
# Overview
The System Monitor can be integrated with an AVL PUMA testbed system to enable unattended tuning. Communication between the PUMA system and System Monitor is established via a serial port using the ASAP3-compliant protocol.
## Capabilities
Using this setup, PUMA can:
- Read and modify editable parameters
- Download editable parameters to the ECU
- Acquire measurement parameters
- Select parameter description and binary data files
!!! note
Only one project (description) and one embedded data (binary) file can be active at a time.
---
# Testbed Operations
- **Configure** — Opens the Testbed Properties dialog box (Shortcut CTRL+SHIFT+F5)
- **Enable Link** — Switches the Testbed Link on and off (Shortcut CTRL+SHIFT+F6)
- **Message Window** — Opens the Testbed Message window (Shortcut CTRL+SHIFT+F7)
## Link
Selecting/deselecting the **Enable Link** command (Tools menu) switches the link between System Monitor and the testbed on and off.
- When the link is enabled, the ECU is put On-Line.
- Note: If Full Operation mode is selected on the Testbed Properties → Link tab, Live Tune is also enabled.
- If the ECU is taken Off-line or Live Tune is disabled, the Testbed link is automatically disabled.
- When the link is enabled, `PUMA enabled` is displayed on the Status Bar.
System Monitor windows can be used to monitor parameter values while the link is enabled. The status of the link, and the information passing across it, are shown on the Testbed Message Window.
The parameters that System Monitor acquires from the ECU are defined in the Live Logging Configuration. Ensure that Auto Configuration is On so that the correct data is available to send to the testbed and to display on the screen.
## Message
To open the Testbed Message window select Tools > Testbed > Message Window.

The window shows information about the communication between System Monitor and the testbed. It consists of the following areas.
### Parameters Bar
PUMA defines a single block of parameters, and declares the rate at which it will request those parameters.
The Parameters Bar displays the following:
- **Params** — the number of parameters in the block
- **Rate** — the rate at which these parameters will be requested
### Message Window
Shows the information which is being transferred between System Monitor and the testbed as follows:
- **Commands** — Mnemonics received from the testbed, for example: ‘Select Parameters for Acquisition’.
- **Arguments** — Information associated with a Command, for example: `Rate: 1s Params: Speed, Gear, Revs..`
- **Messages** — Mnemonics sent in reply to a request for parameter values, for example: ‘Reply to Acquire Parameters’
- **Parameter** — Identifiers and values (in engineering units) of parameters associated with a Message.
- **Debug** — When Debug is on requests repetition of the last message from PUMA to System Monitor or System Monitor to PUMA. Also requests acknowledgements from System Monitor to PUMA that the last message was received.
- **Watchdog** — When Watchdog is on watchdog time-outs are shown in the following form:
- `Byte timeout `, where `bto` is the byte timeout value.
- `Message timeout `, where `mto` is the message timeout value.
- **Errors** — possible values are:
- Command not executed
- Error during execution ``, where `` gives details of the command arguments in error, or the external error that occurred
- Command not available
### Status Bar
- **Link** — Indicates the link status:
- **enabled** — Link is selected, but no bytes have been received
- **disabled** — Link is not selected
- **active** — Link is selected, and bytes have been received
- **inactive** — Link is selected, but a message timeout has occurred
- **Bytes** — the number of bytes since (and including) the last Init command.
- **Message** — Indicates the current message status:
- **waiting** — Waiting for a command
- **received** — Received a command, not yet sent a confirmation or definitive reply
- **confirmed** — Sent a confirmation, not yet sent a definitive reply
- **replied** — Sent a definitive reply, waiting for handshake
- **repeat** — Waiting for PUMA to repeat a command after a byte timeout
- **Last Error** — Shows the last error that occurred. This is displayed even if the link has since recovered from the error.
---
# Testbed Properties
System Monitor must be configured to operate with the testbed.
To open the Testbed Properties dialog box select: Tools > Testbed > Configure.
## Link
Configure the link between PUMA and System Monitor on the **Link** tab.

The tab has the following controls:
- **Mode**
- **Measurement** — PUMA can take measurements from System Monitor. System Monitor only responds to the Initialisation and Data Acquisition commands sent by PUMA.
- **Full Operation** — System Monitor responds to all the commands sent by PUMA.
- **Comms Setup** — Opens the Serial Comm Setup dialog box. The default settings are chosen to suit most applications.
If the setup is not working, check that it conforms to the requirements of your testbed. The setup is saved as part of the Project settings, so it may need to be edited for each project on which it is used.
## Watchdog
Configure the watchdogs on the link between PUMA and System Monitor on the **Watchdog** tab.

**Message Timeout panel**
- **Time Between** — Enter the timeout period. Range: 0.1 to 36,000 seconds. Resolution: 0.1 seconds. Default: 300 seconds.
- **Enabled?** — When checked, the link is terminated if the time between messages exceeds the value in the Time Between field. The link is re‑established by the PUMA testbed.
**Byte Timeout**
- **Time Between** — System Monitor sends a request to the PUMA testbed to repeat the last command if the time between bytes of the same message is greater than the value in this field. Range: 0.1 to 100 seconds. Resolution: 0.1 seconds. Default: 1 second. This feature is always enabled.
!!! note
The Watchdog properties cannot be changed while the Testbed Link is Enabled.
## Debug
Use the **Debug** tab to configure the Debug file.

- **Debug Enabled?** — When checked, the text that appears in the Testbed Message window is copied to the Debug file. If the file already exists, text is appended to it.
- **Debug file** — Enter or browse for the name and path of the file where you want to save the debug information. There is no default path but the default file name is `tb_debug.txt`.
The debug filename cannot be changed if the Testbed Link is Enabled, but debug may be switched on or off.
## Commands
Use the **Commands** tab to configure the way System Monitor responds to [PUMA commands](puma-commands.md).

- **Send command confirmation to PUMA?** — When PUMA sends System Monitor a command, it expects a reply within a certain time. If System Monitor cannot execute the command and reply within that time, a command confirmation message may be sent in place of the reply. This gives System Monitor longer to execute the command and allows the definitive reply to be sent later.
- When a command check box is selected, that command will be confirmed before the definitive reply is sent.
- **View as** — PUMA uses different command names to System Monitor. Commands can be viewed either as the PUMA command names or as their System Monitor equivalents.
## Translate
Use the **Translate** tab to configure the correspondence between System Monitor and PUMA parameter identifiers.

- **Command translation enabled?** — When selected, the parameter identifiers used by PUMA are translated to those used by System Monitor and vice‑versa.
- **Translation file** — Enter or browse for the name and path of the file where System Monitor can find the equivalents list to translate the parameter identifiers.
---
# PUMA Commands
System Monitor supports a subset of commands from the AVL PUMA protocol V2.0. Commands from V1.0 or its sub-versions are not supported.
All values exchanged use engineering units for:
- Measurement parameters
- Editable parameters
- Map breakpoints
- Plausible physical limits
- Minimum increments
## Initialisation Commands
### `Init`
Initialises System Monitor for a PUMA tuning session.
When received:
- Starts the Watchdog (if enabled)
- Opens the Debug File (if enabled)
### `Identify`
Sent by PUMA to declare protocol version and identify itself.
- If version is V2.0 or later: System Monitor replies with its version (V7.0)
- If version is V1.0 or sub-version: System Monitor replies with `command not available` error and rejects all subsequent commands
## Configuration Commands
### `Select Project and Embedded Data`
Must follow an `Init` command.
PUMA must provide:
- Project file name
- Embedded data file name
System Monitor checks program stamps for compatibility. If valid:
- Opens project and embedded data file
- Returns LUN = 1
### `Copy Embedded Data`
Copies data from edit buffer to file.
PUMA must specify:
- Source = 3 (edit buffer)
- Destination = 2 (file)
- LUN = 1
System Monitor writes:
- New data stamp (if filename changed)
- Comment (includes changed parameters and PUMA name)
- User name and date
- Editable parameter values
### `Change Embedded Data Filename`
Changes the filename for future saves.
- Does not save data
- If filename is invalid, returns `error during execution`
## Map Manipulation Commands
### `Select Map`
PUMA nominates a map to read or modify.
System Monitor returns:
- Map number
- Number of breakpoints (x and y axes)
If invalid or not a map, returns `error during execution`.
### `Get Map from System Monitor`
Returns:
- Breakpoint values
- Map site values
- Minimum increment
- Plausible physical limits
### `Put Map to System Monitor`
Sets map values as specified by PUMA.
- Ignores increment and limits
- Caps values outside limits without error
- Returns error if breakpoints are out of sequence
### `Get Map Value`
Returns value of a single map site.
PUMA must specify:
- Map number
- x and y index
### `Set Map`
Sets all map sites in a grid range to a single value.
Returns error if:
- Grid range is off-map
- Values are capped if outside limits (no error sent)
### `Increase Map`
Increases map site values in a grid range.
Returns error if:
- Grid range is off-map
- Values are capped if outside limits (no error sent)
## Scalar Manipulation Commands
### `Get Scalar from System Monitor`
PUMA must send:
- LUN = 1
- Parameter identifier
System Monitor returns:
- Scalar value
- Plausible physical limits
- Minimum increment
> Cannot be used for measurement parameters.
### `Set Scalar on System Monitor`
PUMA must send:
- LUN = 1
- Parameter identifier
- Value
Returns error if:
- Parameter is not editable
- Value is capped if outside limits (no error sent)
## Data Acquisition Commands
### `Select Parameters for Acquisition`
Specifies parameters to be acquired.
PUMA must send:
- LUN = 1
- Sampling rate
- List of parameter identifiers
- Multiple commands append to the list
- Empty list clears all selections
- Updates Live Logging Configuration
Returns error if parameter is not in project description.
### `Switch Offline/Online`
Switches ECU mode.
#### Online Mode:
- Downloads edit buffer changes immediately
- Generates new data stamp
- Accepts `Acquire Parameters` commands
#### Offline Mode:
- Changes affect edit buffer only
- No data is downloaded
- `Acquire Parameters` commands are rejected
!!! warning
Switching modes without saving may result in data loss.
### `Acquire Parameters`
Requests current values for selected parameters.
Returns:
- List of parameter values (in order)
If offline, returns `command not executed`.
## Special Parameters
### `APS_Errors`
#### `Get Scalar`
Returns:
- Number of errors since link enabled
- Min = 0, Max = defined limit, Increment = 1
#### `Set Scalar`
Returns `error during execution`
#### `Select Parameters for Acquisition`
Includes error count in response to `Acquire Parameters`
### `APS_LinkOK`
#### `Get Scalar`
Returns:
- 1 if link is active
- 0 if link is inactive
#### `Set Scalar`
Returns `error during execution`
#### `Select Parameters for Acquisition`
Includes link status (1 = active, 0 = inactive)
## Unsupported Commands
System Monitor does **not** support the following PUMA commands:
### Initialisation
- `Emergency`
### Recording
- `Define Recording Parameters`
- `Define Trigger Parameters`
- `Activate Recorder`
- `Get Recorder Status`
- `Get Recorder Result Header`
- `Get Recorder File`
- `Save Recorder File`
- `Load Recorder File`
### Miscellaneous
- `Set Graphic Mode`
- `Reset Device`
- `Set Format`
## Error Handling
System Monitor may return the following errors:
- **`command not executed`**
Incorrect command sequence
- **`error during execution`**
Invalid arguments or external error (e.g. disk full)
- **`command not available`**
Command not supported in PUMA protocol V2.0
> All errors include an error code and comment.
> Errors are visible in the Testbed Message Window.
## PUMA Errors
Although PUMA is designed for unattended tuning, commands may occasionally fail. System Monitor can return the following error messages:
### `command not executed`
- The command could not be executed due to an incorrect sequence.
- Example: A configuration command sent before initialisation.
### `error during execution`
- The command started but could not complete.
- Causes may include:
- Invalid command arguments (e.g. non-existent project file)
- External issues (e.g. disk full)
### `command not available`
- The command is not supported in PUMA protocol V2.0.
- Typically occurs when using commands from V1.0 or unsupported groups.
### Error Details
- Each error includes:
- An error code
- A comment generated by System Monitor
### Viewing Errors
- Errors are displayed in the **Testbed Message Window**
- The **Last Error** field in the status bar shows the most recent error, even if the link has recovered
!!! reminder
System Monitor only supports one project at a time.
The LUN parameter must always be set to `1`. Any other value will trigger an `error during execution`.
---
# Overview
The ECU Control System Monitor allows programming and monitoring of the ECU via the ECU Menu commands. The program is loaded into System Monitor during the creation of a Program Version. Security features in the Customer Base ensure compatibility between the program and the ECU.
## Key Features
- **ECU Bar**: Displays the status of the ECU.
- **Unit Status**: Shows data versions and configuration files in System Monitor and the ECU units. Supports upload/download of data.
- **ECU Search**: Provides detailed information about the ECU.
- **Kill Engine**: Stops or prevents engine start via the Tools menu.
- **Set ECU Time and Date**: Synchronises ECU time with the PC.
- **Read RAM**: Accesses detailed ECU status information.
---
# ECU Operations
## Selecting Applications
An Application in System Monitor corresponds to a set of ECU Memory locations. Most ECU Control commands operate on the Active Applications.
Commands for Setting Time and Date, ECU Properties, and ECU Search can only operate on one Application at a time. When these commands are selected, the **Select an Application** dialog box is opened.
1. Select one Application and click **OK** to continue.
Commands for Reprogramming the ECU, Force Complete Reprogram, Program Spare Unit, and Upload Sensor Sets can operate on more than one Application. When these commands are selected, the **Select Applications** dialog box is opened.
1. Select one or more Applications by selecting the appropriate check boxes and click **OK**. By default, all the Active Applications are selected.
2. Click **OK** to continue.
## Setting Time and Date
The ECU time and date settings are used to timestamp Events and Logged Data.

**Set the Time and Date:**
1. Select: **ECU > Set System Time and Date.**
2. Select an Application and click **OK.**
3. Configure the **Set System Time and Date** dialog box as follows:
- **New PC:** Enter a new time and date for the computer that you are using. A Calendar is provided for easy date selection.
- **Set PC:** Sets the Time and Date in the computer you are using to the values entered in New PC.
- **Current PC:** Read only. Displays the Time and Date as set on the computer you are using.
- **Set ECU:** Sets the Time and Date in the ECU to the values in the Current PC boxes.
- **ECU:** Read only - Displays the Time and Date set on the ECU.
## ECU On-Line
The ECU must be On-Line to:
- Display or Log Measurement Parameters as defined by the Live Logging Configuration.
- Respond to changes in Editable Parameters during Live Tune.
- Operate with a Testbed.
The ECU can only be On-Line if the link to System Monitor is OK. The Link status is displayed in the Comms Bar.

Select: **ECU > On-line** to toggle the ECU between on-line and off-line modes. This command can be selected even if the Link is not OK. In that case, the ECU will be put on-line as soon as the link is detected.
The time during which System Monitor will try to send a command message is set in the Advanced Settings dialog (Timeout before link lost).
!!! note
System Monitor can be configured to be On-Line whenever a Project is opened by setting **Go online when opening project** to “Y” in Advanced Settings.
When the ECU is On-Line:
- The Comms Bar shows “Monitor ON”.
- The program stamp is read from the ROM of each of the controllers for each Application. If the program stamp does not match the corresponding one in the current Program Version for each controller, the ECU OnLine message box opens with the options:
- **Reprogram:** Reprograms the ECU with the current Program Version then switches the ECU On-Line.
- **Ignore:** Leaves the Program Version in the ECU unchanged and switches the ECU On-Line. System Monitor continues with a mismatch between the Program Versions.
- Closes the message box and the ECU remains Off-line.
!!! note
If **Warn if Program Versions do not match** is set to N in Advanced Settings, the ECU OnLine message box does not appear and Ignore is assumed. Use this setting to allow the ECU to come on-line without user intervention.
When the ECU is Off-Line:
- The Comms Bar shows “Monitor OFF”.
- Acquisition of data is stopped and the most recent values are frozen in the Measurement windows.
- Recording of data to disk is stopped
- The Testbed Link is disabled.
## Kill Engine
The Kill Engine command stops the engine or prevents it from starting. Select: **Tools > Kill Engine** (Shortcut ALT+K).
While Kill Engine is active, System Monitor sends a message to the ECU to stop the engine. The **Sending Engine Kill** message box is displayed and the System Monitor user interface is disabled. However, measurement windows, events, etc. still update.
The engine kill message is sent to all the controllers whose application includes the system constant **ENGINE_KILL_CONTROLLER**. We recommend that you only define the constant in one application, although System Monitor does support sending the message to more than one controller if required.
If the constant is not defined in any application, the message is sent, by default, to controller AC in a TAG-300 unit.
The engine kill message is 0x01a. It is sent continuously at an interval of 200ms. If the message is acknowledged, the indicator in the message box is red; if an acknowledgement is not received for 2s, the engine kill indicator changes to yellow.
To close Kill Engine and allow the engine to start, click **Enable**, or press **ENTER** or **ESC**.
## Cursor Control and Trace
In a 1-axis or 2-axis Map, the active cell is selected by the values of the Breakpoints. The Cursor Control and Trace functions on the ECU Menu use the active cell to assist you with Tuning. They are only available when the ECU is On-Line.
- **Cursor Control:** When checked, the active cell is automatically selected for editing.
- **Trace:** When checked, each cell that has been active since Trace was switched on is outlined in grey.
## Single Message
The Single ECU Message dialog box allows a single message to be sent to the ECU and displays the response. To open the dialog box select: **Tools > Single Message**.

**Comms Path:** Select the Comms Path from the drop-down list. This is only necessary if there is more than one ECU in the vehicle sharing an Ethernet network.
**Message Panel:**
- **Content:** Enter the message that you want to send as a sequence of word-length hexadecimal values. Only valid hexadecimal values are accepted.
- **Words:** The number of words in the message calculated from the message content. Read only.
- **Timeout:** The timeout interval in milliseconds.
- **Send:** Sends the message.
**Repeat Message Panel:**
- **Repeat enabled:** When selected, the message is sent repeatedly when Send is clicked, according to the Interval and Number settings.
- **Interval:** The time, in milliseconds, between repetitions of the message. Only available when Repeat enabled is selected.
- **Number:** The number of times the message is repeated. Only available if Repeat enabled is selected.
**Response panel:**
- **Content:** A read-only hexadecimal display of the response sent by the ECU.
- **Words:** A read-only integer displaying the number of words in the response.
- **Status:** A read-only display of the current response status.
- **OK:** indicates that a response was received from the ECU.
- **Link NOK:** indicates that the ECU is not connected.
- **Timeout:** indicates that a Timeout occurred while waiting for a response.
- **Display all responses:** When selected, all response messages are displayed. When cleared, only responses intended for System Monitor are displayed.
---
# ECU Memory
Electronic Control Units (ECUs) used in motorsport contain one or more controllers with access to two types of memory
**RAM (Random Access Memory)**
- Volatile: requires power to maintain contents.
- Fast, byte/word level modification possible.
- System Monitor can modify RAM while the ECU is On‑Line and running a test.
- The RAM that System Monitor can modify is called Application RAM; it contains the Data Version.
RAM can be changed by:
- Copying ROM to RAM
- Resetting ROM
- Downloading data to the ECU
- Live Tune
**ROM (Read Only Memory)**
- Implemented by programmable non‑volatile devices (EEPROM, Flash‑RAM).
- Programmable only when the ECU is Off‑Line.
- For each controller, ROM is divided into areas: Program, Data and Configurations.
- A whole memory area must be reprogrammed at once; individual memory locations cannot be modified.
ROM can only be changed by reprogramming the ECU.
Most ECUs can operate from either RAM or ROM. To choose, use the Run from ROM or Run from RAM commands. The ECU Bar indicates how each application is running.
## Reprogramming the ECU
The ROM in ECU memory contains:
- Program — programs for all controllers, built from the project Program Version file. System Monitor validates program versions against the Customer Base.
- Data — values of Editable Parameters held in a Data Version file. Systems are tuned by loading different Data Versions.
- Configurations — logging, sensor/actuator calibration, external inputs, etc. System Monitor can program various configurations.
To reprogram the ECU:
1. Select: `ECU > Reprogram Unit`.
- The Select Applications dialog opens. The ROM contents in the ECU are compared with the currently open project; any changed item is downloaded.
- The command is available only if the relevant Customer Base has permission.

2. Optionally select the **Merged program sequences** check box.
- Note: when programming selected applications you may merge programming sequences. When programming sensor sets that cover more than one application, sequences are always merged.
3. Click **OK**.
- A progress message window appears.

!!!warning
Clicking **Cancel** stops reprogramming but does not reset items already reprogrammed. This may leave the ECU in an inconsistent state and could prevent correct operation. If the reprogram sequence does not complete, proper function cannot be guaranteed.
The `ECU > Reprogram All` option reprograms all code and data areas for all applications and downloads the logging configuration — a one‑stop reprogram facility.
!!! note
- Controllers are placed in Boot mode (Zone 0) for programming; successful reprogramming exits Boot mode automatically.
- Logging configurations and other non‑vehicle‑critical data can be programmed in Zone 1 while some ECU functions continue.
- Controller status is indicated on the Comms Bar.
- `Force Complete Reprogram` downloads all program code, data and configurations regardless of change (useful for embedded developers).
- Transfer information to a different unit using Spare Unit procedures.
- Update the Data Version only.
`Tools > Force Complete Reprogram` downloads all program code, data and configurations whether they changed or not. Intended as a diagnostic tool for embedded code developers; for normal updates use the Reprogramming the ECU procedure.
## Run from ROM / Run from RAM
Most ECUs default to running from RAM when connected to System Monitor.
- Select `ECU > Run from ROM` to switch active applications to ROM. The command acts only on Active Applications.
- Select `ECU > Run from RAM` to switch active applications to RAM. The command acts only on Active Applications.
The ECU Bar shows which memory type (RAM or ROM) each application is using.
## Copy ROM to RAM
`ECU > Copy ROM to RAM` sends a signal to copy the Data Version from ROM to RAM. The command acts only on Active Applications. The ECU Bar shows software versions in each application.
## Min/Max Statistics
- Measurement Parameters are typically sensor outputs or ECU calculations.
- The ECU may hold minimum and maximum values of parameters which can be read as Measurement Parameters.
- `ECU > Delete Min/Max` sends a signal to set Minimum and Maximum Measurement Parameters to zero. This command is available only if the relevant Customer Base has permission
- The command applies to Active Applications only.
## Read RAM
The Read RAM window displays RAM contents for a particular controller in the attached ECU. Open it with `Tools > Read RAM`. Multiple Read RAM windows may be opened on the same Desktop.

The Read RAM Properties dialog (Window System Menu icon or Alt + Enter) controls content and layout. Tabs:
- Read RAM — source and format of the data (specific to Read RAM windows).
- Display — appearance controls (common to all windows).
**Status bar**
Shows information about the control unit and its connection:
- Status:
- DataOK — ECU transmitting requested data
- TimeOut — last request did not get a response
- NoData — no data being received
- Controller — controller name as set in Read RAM Properties
- Logging — indicates if data is being logged to a file (set in Read RAM Properties)
**Display memory panel**
- Comms Path — select from drop‑down (needed only if more than one ECU shares an Ethernet network).
- Controller — list of controllers in the connected ECU; select the controller to display RAM contents.
- The Applications dialog Memory Layout tab shows which controllers and locations an Application uses.
- The ECU Properties Controllers tab allows viewing and enabling/disabling controllers.
- Start address — hex address where display starts; must be a word boundary (even).
- Addressing Size — start address of the last block of data to display.
- Format — choose display format:
- Hexadecimal — 4 characters (default)
- Decimal — 5 characters
- Binary — 16 characters
- Floating Point — 14 characters
Memory addresses are always shown in hexadecimal.
- Swap Bytes — when selected, each word’s byte order is reversed.
- Data Only — hide the addresses column when selected.
**Logging panel**
- Log to file — when selected, RAM contents are logged to a file updated at the same rate as the display. The display update rate is set in the Display tab. An indicator shows when logging is active. Default: unchecked.
- Filename — enter or browse for the file name (default: `test1.rrl`). No default path; the most recently opened path is used.
---
# Programming Data
The changes made during Tuning are stored as a Data Version in the Edit Buffer.
Only the Active Applications can be Tuned.
## Live Tune modes
The Data Version may be transferred to the ECU in one of two ways:
- **Live Tune On**
As soon as an Editable Parameter is changed, the new value is loaded into RAM.
- **Live Tune Off**
!!! note
The data changes only affect the ECU RAM. To apply the changes to the vehicle systems, the ECU must be operating from RAM.
## Downloading Data to the ECU
The difference between the data in the Edit Buffer and the RAM are detected and loaded into RAM to make the contents of the RAM match the Edit Buffer when the **Download Data Changes** command is selected.
The command only acts on the Active Applications.
### Download Data Changes
Select: **ECU > Download Data Changes.**

If either the Program Version or the Data Version in the Edit Buffer do not match those in the ECU, a message is displayed with the following options:
- **Sync SM to Unit**
Synchronises the files in System Monitor to match those in the Unit. The specified files are opened in System Monitor, replacing those that are already open. If a file cannot be found, a new file is created using the filename and modification information taken from the unit. Uploads data and places it in the Edit Buffer. Files and data which are the same as already in System Monitor are not uploaded.
- **Reprogram**
Reprograms the ECU then downloads the data changes in the Edit Buffer to the ECU.
- **Force Complete Reprogram**
Forces a Complete Reprogram then downloads the data changes in the Edit Buffer to the ECU.
- **Ignore**
Closes the message box. No changes are made. The download process continues with the next Application.
- **Cancel**
Closes the message box. No changes are made.
## Uploading Data from the ECU
Select: **ECU > Upload Data** to load the Data Version in the ECU into the System Monitor Edit Buffer. You are prompted to save the contents of the Edit Buffer as a new Data Version File.
The command only acts on the Active Applications.
## Undo Data Changes
Data changes can be undone using the following ECU menu options:
- **Undo Data Changes in the Unit**
Undo data changes that have been downloaded to the ECU but do not undo the changes in the Edit Buffer.
- **Undo Data Changes in the Unit and Edit Buffer**
Undo data changes downloaded to the ECU and undo changes in the Edit Buffer.
- **Undo Data Changes in the Edit Buffer**
Undo data changes in the Edit Buffer. Changes downloaded to the ECU will not be undone.
!!! note
The Undo Data Changes commands can only undo changes made since the Data Version was last saved.
## Reset ROM
The **Reset Data to ROM** command in the ECU menu does the following:
1. Overwrites the contents of the Edit Buffer with the Data Version that was used to open the Project. This is equivalent to restoring all values.
2. Reprograms the ECU with the contents of the Edit Buffer.
3. Sends a signal to the ECU to copy the Data Version from the ROM to the RAM.
The command only acts on the Active Applications.
---
# Diagnostics Status
This section covers tools and views that help users inspect ECU status, synchronize files, and verify program and data versions.
## Unit Status
The Unit Status dialog box indicates which files have been loaded into the Edit Buffer and the unit, and is used to synchronize the two. The dialog box is resizable and the column widths are editable.
To open the dialog box, select: **Tools > Unit Status**. To select more than one cell, use the SHIFT and CTRL keys.

### Columns
| Column | Description |
|----------|-----------------------------------------------------------------------------|
| **Project** | Information about the files currently loaded into System Monitor. |
| **ECU** | Information about the files currently loaded into the Main unit. |
| **Spare** | Information about the files currently loaded into the Spare unit. This column is only shown if the Spare check box is selected. |
### Rows
| Row | Description |
|--------------------|-----------------------------------------------------------------------------------------------------------------------|
| **Data Versions** | For each Application. |
| **Sensor Sets** | Allows you to apply calibration data to sensors, enable and disable individual sensors, and enter values for sensor constants. |
| **Configurations** | The Remote logging, Burst logging, and External Inputs configurations are stored in and used by an ECU when it is working independently of System Monitor. |
| **History** | During its operation, the ECU generates various statistics about the operation of the vehicle that it is controlling. |
### Cell Colours
The background colours of the cells indicate the following:
- **White** - Unit contains the same information as in System Monitor.
- **Red** - Unit contains a different program or data version from the one in System Monitor.
- **Orange** - Unit contains the same program and data version but different Live Tunes.
- **Blue** - Unit contains a different configuration (sensor set, remote logging, burst logging, external inputs, history report).
- **Yellow** - Selected cell. A summary of the file history is displayed at the bottom of the dialog box for the selected cell.
### Other Symbols
The following symbols may also appear:
- `(*)` - The data has been modified and not yet saved.
- `?` - System Monitor is unable to obtain the information from the ECU.
- `(L)` - DTV has been locked with standard RDA.
- `(L2)` - DTV has been locked with enhanced RDA2.
### Controls
With a cell or cells selected, the following commands are available:
- **Refresh** - Updates the display.
- **<>** - Download the information for cells selected in the Project column to the main unit. Only downloads data that is not the same as already in System Monitor. For Data Versions, runs Force Complete Reprogram before downloading data.
- **Sync Unit>>** - Synchronize the information in the main unit with the data in the Edit Buffer. This command only applies to cells selected in the Project column. If the Program or Data versions are different, runs Reprogram Unit then Download Data Changes. Configuration files that are the same as already in System Monitor are not downloaded.
- **All Sync Unit>>** - Synchronize all files in the main unit with the data in the Edit Buffer. This command is the same as selecting all cells in the Project column and clicking Sync Unit.
- **Spare>>** - As Download>> but sends information to the Spare unit. Only available when the Spare column is displayed.
- **Sync Spare>>** - As Sync Unit>> but sends information to the Spare unit. Only available when the Spare column is displayed.
- **All Sync Spare>>** - As All Sync Unit>> but sends information to the Spare unit.
- **Spare** - When this check box is selected, the Spare column is displayed. Only available if a Spare Unit has been configured.
## ECU Properties - Controllers
The Controllers tab of the ECU Properties dialog box allows controllers within the ECU to be viewed and enabled/disabled.

All the Applications are shown in a list. Click the expand icon to see the controllers connected to an Application. The check box beside the controller indicates its status. When selected, the controller is connected to the application and responds to reprogramming, tuning, and monitoring. When cleared, the controller is disconnected from the application and does not respond.
Controllers are connected or disconnected by selecting or clearing the check box for the Application. If an Application is connected to some, but not all, of the controllers, its check box is greyed out.
## ECU Properties – Devices
The Devices tab of the ECU Properties dialog box displays information about the ECU hardware.

Each unit is shown in the following format:
```
aaaaa (Detected Name: bbbbb)
```
Where `aaaaa` is the type of ECU as specified in the Program Version, and `bbbbb` is the type of ECU as detected by interrogating the unit (should be the same as `aaaaa`).
Click the expand icon to see the following:
- **Serial Number** - The serial number of the ECU as detected by interrogating the unit.
- **Address** - The IP Address of the ECU as defined in Unit Definition.
## ECU Search
The ECU Bar displays Data Version information for all Applications. ECU Search provides more detail about the Program and Data Version Files loaded into the ECU.
To initiate an ECU search, select: **ECU > Search for Versions**.
Following Application selection in the **Select an Application** dialog box, the ECU Search dialog box opens. The ECU Search dialog box consists of the following tabs:
### Program Version on ECU
The Program Version tab of the ECU Search dialog box displays the Filename, Saved By, Saved On, Comment, and Notes information for the Program version on the ECU. The files used to create the Program version are shown in the Properties list. The file name of the original Data version, generated when the Program Version was created, is shown as **Base Data**.

All the information on this tab is read-only.
### Data Version in Flash-RAM
This tab shows information about the Data Version being used by the ECU.

When an ECU is connected, System Monitor locates the files that were used to program it. The ECU does not hold the file name but stores an ID which System Monitor can use to identify the file.
System Monitor searches for files when:
- A new project is loaded.
- The ECU memory is changed.
- The ECU is reconnected after the link has been lost.
A search can also be forced by the **Query Versions** command on the ECU Menu.
The Program Version ID is taken from the Reference Controller. If that controller is faulty or not connected, System Monitor cannot locate the Program Version and `???` is shown in the ECU Bar. Ensure that the Reference Controller is enabled in **ECU Properties - Controllers**.
Data Version file locations are searched in the following order:
1. The directory that contains the data version currently loaded into the project.
2. The directory and sub-directories that were created to contain the same program version as detected in the ECU.
3. The entire Customer Base directory and sub-directories.
Once the Data Version file is located, its contents are compared with the settings of all the controllers in turn. If the data in any controller is different from the version in the file, `(*)` is shown in the ECU Bar.
The status of the search is indicated by the background colour of the ECU Bar.
The search can take some time. To speed up the response of the ECU Bar, System Monitor can be prevented from searching the entire Customer Base directory. To do this, set **Search base for versions** to `N` in **Advanced Settings**.
---
# Hardware
## Adjustment board
The Adjustment Board is a box with four high‑precision rotary switches. System Monitor can map each switch to a Measurement Parameter (used as an Index Parameter in a 1‑axis or 2‑axis map) or to a scalar editable parameter. This lets operators adjust control values by feel while watching System Monitor and other instruments.
All controls operate the same; the knobs differ in size to aid identification. Turning clockwise increases the assigned parameter; turning counter‑clockwise decreases it.
### Configuration
To configure the Adjustment Board:
1. Open the **Pot Board Configuration** dialog:
- Navigate to `Tools > Pot Board > Configure`
- Shortcut: `CTRL + SHIFT + F1`
2. Assign parameters to controls:
- Drag parameters from the **Parameter Explorer** to the corresponding row in the configuration window.
- Each row corresponds to a labelled control on the board.
3. Remove assignments:
- Right-click a parameter in the configuration window and select **Remove**.
4. Assign a control to the **Maths Bar**:
- Right-click a row and select **Maths Bar**.
- Turning the assigned control adjusts the selected editable parameter.
### Adjustment Groups
Parameters are assigned in groups of four, matching the four physical controls on the board. These groups are defined in the `Pot.ini` file used during program version creation.
- The active group is selected in the **Adjustment Board Configuration** dialog.
- Group names and assignments can be edited in the **Adjustment Board Groups** dialog.
### Supported Parameter Types
- **Scalar Editable Parameters**: Turning a knob is equivalent to changing the parameter value manually.
- Each parameter includes an **Adjustment Properties** tab to define:
- **Step size**
- **Zero value**
### Keyboard Operation
The keyboard can replicate Adjustment Board functionality:
- **Increase value**:
- Hold `CTRL` and press a number key (1–4)
- **Decrease value**:
- Hold `CTRL + SHIFT` and press a number key (1–4)
> Use the number keys on the main keyboard, not the number pad.
Step size is defined in the **Adjustment Sheet** of the Parameter Properties.
### Pot Board Properties
To configure the connection between System Monitor and the Adjustment Board:
1. Open the **Window Properties** dialog:
- Shortcut: `ALT + Enter`
2. Navigate to the **Pot Board** tab.
3. Select connection type:
- **CA Card**
- **Serial Port** (COM1 or COM2)
> The serial port is configured automatically to suit the board, regardless of Windows settings.
### Adjustment Board Menu Commands
Located under `Tools > Pot Board`:
- **Configure**: Opens the configuration dialog (`CTRL + SHIFT + F1`)
- **Enable**: Activates the controls (`CTRL + SHIFT + F2`)
- **Reset Adjustments**: Function depends on parameter type (`CTRL + SHIFT + F3`)
- **Recent Files**: Lists recently opened configuration files
### Available types
#### VE‑80
- Passive device using dedicated connections on the CA‑card.
- Connection details are in the CA‑card product specification.
- No separate power supply required.
- In the Adjustment Board Configuration dialog, select **CA Card** on the Link panel.
#### VE‑81
- Active device connected via an RS‑232 serial port.
- Connect the VE‑81 to an RS‑232 port on the PC using the supplied cable.
- Connect the provided power supply to the VE‑81 and a suitable AC outlet. The rear LED flashes once per second when the unit is powered and transmitting.
- In the Adjustment Board Configuration dialog, select **Serial Port** on the Link panel and choose the COM port (e.g., COM1 or COM2).
!!! note
The Adjustment Board is often called a "Pot" or "Potentiometer Board." This is not strictly accurate: a potentiometer gives an absolute output for a given position, whereas the rotary switches on the Adjustment Board produce a pulse train and direction. Switch position has no absolute value.
## CAN link
CAN (Controller Area Network) is a serial data protocol originally developed for automotive use and now common in industrial applications. The protocol is defined in ISO 11898.
Key characteristics:
- Access is controlled by non‑destructive, bit‑wise arbitration.
- Messages are compact (up to eight data bytes) and include a checksum.
- Messages carry numeric identifiers rather than explicit addresses; the identifier determines priority and can indicate message content.
- Robust error handling retransmits messages if necessary.
- Faults are isolated and faulty nodes are removed from the bus.
System Monitor can be used to configure an ECU or data logger to interpret sensor data on a CAN link.
---
# Developer Functions
System Monitor includes various features available for experienced operators. These come under the following categories:
- **Diagnostics** — Provides information for embedded software developers and can be useful for troubleshooting the operation of the ECU and of System Monitor itself.
- **System Log** — Files of errors and events that occur during the operation of System Monitor.
- **Productivity Tools** — Allows repetitive processes to be automated and provides links with other applications.
- **Settings** — Changes various System Monitor configuration settings.
- **FIA Upload** — A utility for verifying that the code in the ECU meets FIA requirements.
## Diagnostics
Diagnostics provides information for embedded software developers and can be useful for troubleshooting the operation of the ECU and of System Monitor itself.
The Diagnostics tools are accessed from the Tools menu.
The following tools are available:
- **Read RAM** — Opens a window that displays the content of the memory for a particular controller in the attached ECU. (Shortcut: `ALT+R`)
- **Single Message** — Allows messages to be sent to the ECU and to view the response. (Shortcut: `ALT+M`)
- **Force Complete Reprogram** — Downloads all the data and code for the ECU whether it has changed or not. (Shortcut: `ALT+C`)
Only available when an ECU is connected.
## System Log
System Monitor creates files of errors and events that are caused by its own operation. (These are not the same as the Errors and Events which are due to the operation of the ECU.)
The contents of the files typically correspond to the on-screen messages but with much more detail.
The following files are created:
- `Pgv_xxx.txt` — log of messages generated when Creating Program Versions.
- `Cmd_xxx.txt` — log of commands issued from Menu commands or ActiveX.
- `Warn_xxx.txt` — log of warnings, in particular Parameters dropped from configurations, etc.
- `Unit_xxx.txt` — log of communications with the unit.
Where `xxx` is the username of the person logged onto the computer running System Monitor.
The directory for log files is defined in Advanced Settings. If no location is defined, the files are not created.
### Message Logs
A further level of detail is available in a Message Log which is used for debugging.
To create a Message Log:
1. Enable logging by selecting a log level in the **Message log level (for debugging)** Advanced Setting. This is normally set to Not Logging.
2. Write the log to the directory by clicking the Log IP Transaction button on the Standard Tool Bar.
The following file is created:
- `SM_Msgs_xxx.txt`
All log files are in ASCII format and can be read by any text editor.
### Error Messages During Operation
The messages linked to this topic should not occur during normal operation. They indicate that there may be a problem with your System Monitor installation or with your ASAP or Hex files.
## Productivity Tools
Productivity Tools allow repetitive processes to be automated and also provide links with other applications. The following tools are available:
- **Custom Menus** — Run applications other than System Monitor from menu commands in System Monitor.
- **Macros** — Record and play back sequences of keystrokes.
### Custom Menus
System Monitor includes a facility to run external applications.
Custom Menus creates additional entries in the Tools menu, which run executable files. The Custom Menu facility can be used for scripts and the McLaren Applied support team may use this facility to provide you with special functions in System Monitor.
Custom Menus are stored in the Windows Registry as part of the System Monitor application and are available to all Projects.
To open the Custom Menus dialog box, select: Tools > Customize.
Create a new custom menu entry:
1. Click `image\Custom_Menu_new_icon.gif`.
2. Enter the text that you want to appear in the Tools menu and press ENTER to accept it.
3. In the Command text box enter or browse for the name of the executable file that you want to be run by the menu entry.
4. Enter Arguments or Working Directory, if required.
5. Click Close to accept the menu entries.
Existing entries can be edited if required. When an entry is selected in the Menu Contents list, its Command, Arguments and Working Directory text boxes can be edited. To rename an entry, select it in the Menu Contents list, then click on it.
- `image\Custom_Menu_delete_icon.gif` — Deletes the selected entry.
The menu entries appear in the Tools menu in the same order as they appear in the Menu Contents list.
- `image\Custom_Menu_up_icon.gif` — Moves the selected entry one place up the list.
- `image\Custom_Menu_down_icon.gif` — Moves the selected entry one place down the list.
### Macros
System Monitor includes a facility to record keystrokes and to replay them as Macros. Macros are stored in the Windows Registry as part of the System Monitor application and are available to all Projects.
!!! note
Mouse movements are not recorded.
To open the Macros dialog box, select: Tools > Macros.
Record a new macro:
1. Click Record to open the Record New Macro dialog box.
2. Enter a Description.
3. Enter a Shortcut key sequence. The shortcut consists of one or more control keys (`CTRL`, `ALT` or `SHIFT`) and a function key or any letter or number.
4. Select the number of times you want the Macro to repeat on playback. The default is `0`. Check Repeat Forever if you want the Macro to continue to repeat until you press `CTRL+ESC`.
5. Select the Playback Speed that you want the Macro to run at. The default is `x1`.
6. Click OK. The dialog boxes close and all keystrokes are recorded until you press `F2`.
The Description, Shortcut, Repetition and Playback Speed of the selected macro can be edited in the Macro dialog box.
To delete a macro, select it from the Macros list and click Delete.
To play or stop a macro:
- To play a macro, select it from the Macros list and click Play. Alternatively, you can play a macro by pressing the shortcut key sequence; the Macro dialog box must be closed.
- To stop a macro that is playing, press `CTRL+ESC`.
## FIA Upload
System Monitor includes a utility for verifying that the code in the ECU meets FIA requirements. The utility is a separate program that runs outside System Monitor. It is installed with System Monitor in the same location as the System Monitor files.
For more information on using the FIA Upload utility, please contact Technical Support and ask for the Working Practice Document “Uploading Code and Data for FIA Software Checks” TWPD0066.
---
# Overview
During its operation the ECU generates various statistics about the operation of the vehicle that it is controlling. History Report extracts these statistics and displays them. System Monitor can also control aspects of the way the statistics are collected and stored.
History Report is only available if the relevant Customer Base has permission, as set in Customer Base Advanced Settings.
Before History Reports can be used, a History Report file must be associated with the Project.
Select **Tools > History Report** to access the submenu options.
**Menu Options**
| Option | Description |
|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **Open filename** | Opens the History Report dialog box for the History Report File currently associated with the project. If there is no History Report file, this command is not available. To open a different History Report file. |
| **Upload** | Extracts history data from the ECU and opens the History Report dialog box showing that data. The contents of the History Report file associated with the project are overwritten. If there is no History Report file, a new one is created. |
| **Download** | Sends the history data in the currently opened History Report to the ECU. The previous set of history data in the ECU is deleted. Use this facility if you want to continue gathering data for a vehicle in which you have changed the ECU. This command also sends Setup data to the ECU. **Note:** Only available when a History Report dialog box is open. |
| **Reset Engine Stats** | Sets the value of all the history data for engines in the ECU to Zero. The previous set of history data for engines is deleted. **Note:** Only available when a History Report dialog box is open. |
| **Reset Chassis Stats** | Sets the value of all the history data for chassis in the ECU to Zero. The previous set of history data for chassis is deleted. **Note:** Only available when a History Report dialog box is open. |
## Selecting a History Report File
An existing History Report File can be selected from the File Type Selection dialog box. When selected the History Report dialog box opens, showing data from the file.
---
# Details
## Files
The History Report files are stored in the `\HistReps\` sub-directory of the Multi-Application Base. The default name for the History Report is `XXXXXnnn.hrs`, where:
- **XXXXX**: The first five characters of the first Application Name in the project.
- **nnn**: A three-digit hex number, starting with 001, which is incremented whenever a new History file is saved.
The History Report File name is displayed in the Titlebar. When **Tools > History Report > Upload** is selected, the new History Report is given a file name with the next sequential number for the Active Application.
History Report Files can be saved. If you make any changes to the history data, including uploading from the ECU, you will be prompted to save the History Report file when you close the History Report Dialog Box. Use **Save As** on the File Menu if you want to save a History report file under a different name.
The History Report dialog box is opened when:
- An existing History Report File is opened using the **File > Open** command.
- **Tools > History Report > Upload** is selected.
- A new History Report File is created using the **File > New** command.

The dialog box has two tabs:
- **Summary**: Shows totals of statistics for all the Chassis and Engines for which history data has been obtained and gives access to detailed reports.
- **Setup**: Allows modification of how history data is collected.
## Summary
The Summary tab shows totals of statistics for all the Chassis and Engines for which history data has been obtained. The ASAP file defines the number of variants of Chassis and Engine for which history data is analyzed. Each Chassis variant has a row in the Chassis panel, and each Engine variant has a row in the Engine panel. The check box in the Active column indicates which data set is currently being collected by the ECU.

### Chassis Panel
The No, Chassis, Driver, and Notes columns contain text boxes to annotate the history data.
### Engine Panel
In the Engine panel, the text boxes are in the Engine and Notes columns. Click on a text box to open it for editing. The Dist, Time, and Cycles (Engine panel only) columns show the total distance, time, and number of cycles run by the Engine or Chassis since the History Report was last reset.
To see the Chassis Details, select a row in the Chassis panel and press ENTER or double-click in the Active column. To see the Engine Details, select a row in the Engine panel and press ENTER or double-click in the Active column.
To send changes to the ECU, select: **Tools Menu > History Report > Download**.
## Chassis Details
To open the Chassis Details dialog box for the selected chassis data set, click on a row in the Chassis panel in the Summary Sheet of the History Report. The dialog box displays read-only statistics for the selected Chassis.

- **Chassis**: Text information from the row for that Chassis in the History Report - Summary.
- **From**: The date that the Chassis data was last reset.
- **To**: The date that the history data was uploaded.
- **Total Distance**: The distance accumulated by the chassis between the From and To dates.
- **Total Time**: The time accumulated by the chassis while history data was being recorded.
- **Time in Gear**: A breakdown of the time the chassis was in each gear.
## Engine Details
To open the Engine Details dialog box for the selected engine data set, click on a row in the Engine panel in the Summary Sheet of the History Report. The dialog box has the following tabs:
- **Time**: Shows a breakdown of the amount of time that the selected engine was in selected combinations of engine speed and throttle opening.
- **Cycles**: Shows a breakdown of the number of cycles during which the selected engine was in selected combinations of engine speed and throttle opening.
- **Auxiliary**: Shows diagnostic data for the selected engine.

Some aspects of the data shown in the Engine Details dialog box can be modified in the Setup tab of the History Report Dialog Box. Click **Print** to print a text version of the information on the selected tab.
### Time
The Time tab shows a breakdown of the amount of time that the selected engine was in selected combinations of engine speed and throttle opening. The dialog box displays read-only statistics for the selected Engine.
- **Engine**: Shows the text information from the row for that Engine in the History Report - Summary.
- **From**: The date that the Engine data was last reset.
- **To**: The date that the history data was uploaded.
- **Total Cycles**: The number of cycles accumulated by the engine while history data was being recorded.
- **Total Time**: The time accumulated by the chassis while history data was being recorded.
**Features**:
- The upper pane shows a breakdown of the time spent by the selected engine in each combination of engine speed and throttle opening.
- The lower pane shows the same data as a percentage of the total time.
- The Breakpoint values can be modified in the Setup tab of the History Report dialog box.
### Cycles
The Cycles tab shows a breakdown of the number of cycles during which the selected engine was in selected combinations of engine speed and throttle opening. The dialog box displays read-only statistics for the selected Engine.
- **Engine**: Shows the text information from the row for that Engine in the History Report - Summary.
- **From**: The date that the Engine data was last reset.
- **To**: The date that the history data was uploaded.
- **Total Cycles**: The number of cycles accumulated by the engine while history data was being recorded.
- **Total Time**: The time accumulated by the chassis while history data was being recorded.
**Features**:
- The upper pane shows a breakdown of the number of cycles during which the selected engine was in each combination of engine speed and throttle opening.
- The lower pane shows the same data as a percentage of the total time.
- The Breakpoint values can be modified in the Setup tab of the History Report dialog box.
### Auxiliary
The Auxiliary tab shows diagnostic data for the selected engine. The dialog box displays read-only statistics for the selected Engine.
- **Engine**: Shows the text information from the row for that Engine in the History Report - Summary.
- **From**: The date that the Engine data was last reset.
- **To**: The date that the history data was uploaded.
- **Total Cycles**: The number of cycles accumulated by the engine while history data was being recorded.
- **Total Time**: The time accumulated by the chassis while history data was being recorded.
The list shows a breakdown of the Battery Voltage and Alternator Current against engine speed. Note: The Breakpoint and Condition values can be modified in the Setup tab of the History Report dialog box.
### Conditions Panel
The Conditions panel shows the Total Time and the Longest individual period that the engine was in the following states:
- Oil temperature (T_Oil) is lower than condition while Oil pressure (P_Oil) is greater than condition.
- Oil pressure (P_Oil) is lower than condition while Engine Speed (Revs) is greater than condition.
- Water Temperature (T_Water) is greater than condition.
### Statistics
- **Max Revs seen**: The highest engine speed reached while the history data was being recorded.
- **Soft Rev-limit**: The number of occurrences of Soft rev limits (i.e., engine speed high enough for the ECU to retard the ignition). Also shown as a percentage of the Total Cycles.
- **Hard Rev-limit**: The number of occurrences of Hard rev limits (i.e., engine speed high enough for the ECU to cut the ignition). Also shown as a percentage of the Total Cycles.
- **Num Rev-limits**: The number of times that the number of consecutive Rev-limit incidents exceeded condition. The maximum number of consecutive Rev-limit incidents is also shown.
## Setup
The Setup tab allows you to modify how history data is collected.

### Rev Breakpoints
Edit the breakpoints to modify the ranges of engine speed used to display statistics in the Chassis Details and Engine Details dialog boxes. The default for Number of Breakpoints is 16, which can be edited to a lower value (must be a positive integer). The breakpoints between the new number and 16 are labeled "Unset". All breakpoint values, except the first, can be edited.
### Throttle Breakpoints
Edit the breakpoints to modify the ranges of throttle opening used to display statistics in the Engine Details dialog box. The Number of Breakpoints is fixed at 5. Each breakpoint value, except the first and the last, can be edited.
### Conditions
Edit the values used for conditions in the Auxiliary Engine Details dialog box:
- **Low Oil Temp/High Oil Pres Condition**: Oil temperature is lower than T_Oil ºC and Oil pressure is greater than P_Oil bar.
- **Low Oil Pressure/Normal Running Condition**: Oil pressure is lower than P_Oil bar and Engine Speed is greater than Revs rpm.
- **High Water Temperature condition**: Water Temperature is greater than T_Water ºC.
- **No. of long rev-limits condition**: The number of times that the number of consecutive Rev-limit incidents exceeds FiresInLimit.
To send changes made on this dialog box to the ECU, select: **Tools > History Report > Download**.
---
# Overview
Organise and retain vast telemetry datasets in a structured, scalable format.
## SQL Race Management Studio (SRMS)
SRMS streamlines the storage and access of racing telemetry. Designed for teams handling large data volumes, it enables efficient session organisation, import automation, and secure database‑backed retention.
### Key Functionality
- Session management tools
- Centralised data storage with user controls
- Bulk import
- Auto‑import for routine ingestion
---
# Overview
SQL Race is the session data access layer used by ATLAS to manage telemetry data. It provides a structured way to store, retrieve and manipulate session data, supporting both real-time and historical analysis. SQL Race integrates tightly with the tools in the ATLAS product suite, enabling efficient data handling, and customisation via the [SQL Race API](../../../developer-resources/atlas/sql-race/index.md).
SQL Race Database is a custom SQL Server implementation specific for data store. It supports MS SQL Replication where replication of data is required over multiple sites.
## Core Capabilities
1. Session Management: Handles creation, loading and association of sessions, including composite sessions for comparitive analysis.
2. Data Access Layer: Provides APIs for reading, and writing data. Including parameters, events and session summaries.
3. Filestream integration: Uses SQL Server with filestreams for efficient storage of large binary data such as channel and event logs.
- __Setup with SQL Race__
---
Learn how to install SQL Server and SQL Race Database.
[→ Getting started](installation.md)
- __Start using the SQL Race API__
---
Automate access to sessions, parameters and events.
[→ API Guide](../../../developer-resources/atlas/sql-race/index.md)
---
# Getting Started
This guide will cover the process of installing SQL Server, setting up a SQL Race Database, and connecting your database to ATLAS ready to start reading and writing data.
## Installing SQLServer
Download and install SQL Server 2017 or 2019 from the [Microsoft SQL Server Downloads](https://www.microsoft.com/en-us/sql-server/sql-server-downloads) page.
!!! note
Express will work too but it has limited size so it's not recommended to use for larger datasets.
{: style="max-width:75%;"}
Once the installer has been downloaded, run it and select the 'Custom' installation type and follow the prompts to complete the installation after which the installation center will open.
{: style="max-width:75%;"}
Go to **Installation** and select **New SQL Server stand-alone installation** at the top. Click through the wizard, if you need SQL Server Replication, make sure the checkbox is selected on the **Feature Selection** page.
{: style="max-width:75%;"}
Give the instance a name on the **Instance Configuration** page. It's recommended to use a named instance (like `LOCAL`) instead of leaving it blank, which does not work well with SQL Race Functions.
{: style="max-width:75%;"}
In **Database Engine Configuration** ensure Windows authentication mode is selected and add the current user to the SQL Server administrators. Go the the **FILESTREAM** tab and enable all three options, and add your instance name to the Windows share name (e.g. `LOCAL`).
{: style="max-width:75%;"}
## Installing SQL Server Management Studio (SSMS)
You can download SQL Server Management Studio (SSMS) from the [Download SQL Server Management Studio (SSMS)](https://learn.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms) page. Or from the INstalaller center after installing SQL Server by going to **Tools > Install SQL Server Management Tools**.
## Configuring Firewall
If you want to access the SQL Server instance from another machine, you need to configure the firewall to allow incoming connections via certain ports. Open PowerShell as an administrator and run the following commands:
```powershell
New-NetFirewallRule -DisplayName "SQL Server" -Direction "Inbound" -Protocol "TCP" -LocalPort "1433" -Action "Allow"
New-NetFirewallRule -DisplayName "SQL Server" -Direction "Inbound" -Protocol "UDP" -LocalPort "1434" -Action "Allow"
New-NetFirewallRule -DisplayName "SQL Server" -Direction "Inbound" -Program "%ProgramFiles%\Microsoft SQL Server\MSSQL12.LOCAL\MSSQL\Binn\sqlservr.exe" -Action "Allow"
```
## Enabling TCP/IP
Open SQL Server Configuration Manager and navigate to **SQL Server Network Configuration > Protocols for [YourInstanceName]**. Double-click on **TCP/IP** and select **Enable**, **Apply**, and **OK**.
{: style="max-width:75%;"}
You need to restart the SQL Server service for the changes to take effect. You can do this in SQL Server Configuration Manager by going to **SQL Server Services**, right-clicking on your SQL Server instance, and selecting **Restart**.
{: style="max-width:75%;"}
## Installing SQL Race Database
You can find the latest version of SQL Race Database on the [Portal](https://portal.mclarenapplied.com/portal/Downloads/Software#SQL%20Race%20Database).
Download and run the installer, accepting the license agreement. The installer should automatically detect your SQL Server instance. If it doesn't, you can manually enter the instance name you specified during installation (e.g. `SERVER_NAME\INSTANCE_NAME`).
{: style="max-width:75%;"}
Leave all default options and click **Install**.
### Setting Filestream
SQL Race doesn't use native filestreams, so you must create your own directory. Create a new folder on your C: drive called `SQLRace_FileStream`. When connecting to SQL Race Database from a remote machine, you'll need to access the folder you just created. Right click on the folder, go to **Properties > Sharing > Advanced Sharing**, check **Share this folder**, and click **Permissions**. Ensure that the user you are connecting with has at least **Read/Write** permissions.
{: style="max-width:50%;"}
The folder will be available on the network at `\\YOUR_COMPUTER_NAME\SQLRace_FileStream`.
{: style="max-width:50%;"}
!!! note
If the user accessing the filestream is in a different AD group then follow the steps [here](#cross-domain-access) to enable cross domain access.
## Connecting to SQL Race Database from ATLAS
In ATLAS, go to **Tools > Database Connection Manager** and Click **Add**.
{: style="max-width:75%;"}
!!! note
It's preferrable to match the case of the host machine. So if the machine name is all caps, use all caps in the connection string.
Click **Test Connection** to make sure the filestream is writeable.
!!! failure
If your filestream is readonly, you will see the message "You are able to access only data to read." In this case, make sure you have read/write access to the folder.
!!! success
If the connection is successful, you should receive the message "Established connection to database successfully. FIle stream folder is writeable."
### Cross Domain Access
It is also possible to access SQL Race from a client machine in a different AD group.
#### Windows Credentials
From **Credentials manager > Windows credentials > Add a Windows Credential**
{: style="max-width:100%;"}
When asked for an Internet or network address, you need to provide the IP or fully-qualified domain name (FQDM), followed by port 1433. Then give a valid username and password for the REMOTE server, ensure the user have permission to view the databases and access the filestreams.
#### SQL Server Settings
In SSMS, right click the **Server instance > Properties > Connections > Allow remote connections to this server**
{: style="max-width:100%;"}
In **Sql Server configuration manager > SQL Native Client 11.0 Configuration**. Ensure TCP/IP is enable and move it to order 2.
{: style="max-width:100%;"}
In **Sql Server configuration manager > SQL Server Network Configuration > Protocols for {instance name}** (for a default instance, the instance name would be MSSQLSERVER). Ensure TCP/IP is enabled.
{: style="max-width:100%;"}
Right click **TCP/IP > Properties**. Make all TCP Dynamic Ports blank and TPC Port to be 1433
{: style="max-width:60%;"}
{: style="max-width:60%;"}
Apply all setting and restart the service.
On the server, run command ```netstat -a -p``` tcp and make sure port 1433 is listening.
#### Test Remote Connection with SSMS
On your local machine, launch SSMS and use the following connection string: **{IP/ FQDM},1433**. For example: 10.1.123.123,1433 or 10.1.123.123,1433\MSSQLSERVER
{: style="max-width:100%;"}
Use Windows Authentication as the authentication method, the Windows Credential that we have set up earlier means that when you connect to the remote it will use that credential instead.
!!! tip
If you encounter this error message:
{: style="max-width:100%;"}
That means your local machine cannot connect to the remote server. Ensure that remote connect is enabled and the protocols and port numbers are set correctly as outlined above.
!!! tip
If you encounter this error message:
{: style="max-width:100%;"}
Check your Windows Credential, this could be because the local credentials were passed, or because the username didn't include the domain prefix or used the wrong domain name. Double check all of the properties of the stored credential and recreate it if you need to (you can modify the username and password, but if the server name is wrong, you'll need to re-create it).
#### Enter connection details in ATLAS
The setting below might be required when using .NET Framework connecting to a SQL server in a MultiSubnet Environment. Follow the [link](https://techcommunity.microsoft.com/blog/sqlserversupport/connection-timeout-issue-with-net-framework-4-6-1---transparentnetworkipresoluti/318791) for more info.
```TransparentNetworkIPResolution = False```
To connect to this database, navigate to the Connection Manager in ATLAS as normal, and enter **{server IP}\{instance name},1433**
The server’s name will not be present in the dropdown. But after entering the server name and let ATLAS connect to the database, the database name should be populated with all the available databases.
{: style="max-width:100%;"}
This should also create a corresponding entry in the the ```C:\Users\...\Documents\McLaren Electronic Systems\SQL Race Server\Config\ConnectionManagerV3.config``` file.
#### Using the SQLRace API
To read and write to databases cross domain, an entry would be required for the corresponding database in ConnectionManagerV3. Refer to the last section for the correct format.
In the code, the connection string to be used for the SessionManager should be:
```
const string ConnectionString = @"Data Source=tcp:10.1.162.152\LOCAL,1433; TransparentNetworkIPResolution = False; Initial Catalog=SQLRACE02_155;Integrated Security=True;";
```
#### Access to the filestream
Depending on the SQL Race filestream is access controlled, you may have to follow similiar steps to allow access to the filestream folder using a different domained account.
---
# Performance Guide
This guide covers settings on how to get the most out of your SQL Race installation by adjusting settings for better performance.
## Cache Settings
The SQL Race cache is a key component of SQL Race memory management, designed to optimize data access time by keeping recently added or loaded data in memory. Operations in RAM are much faster than continuously reading and writing data directly from disk. Raw channel and event data is stored in memory in “slots” created during recording new data or loading historical data.
The cache settings can be modified and are stored by default in the configuration file
SettingsStoreDefault.config located at:
`C:\Users\{USER.NAME}\Documents\McLaren Electronic Systems\SQLRace\Config\SettingsStoreDefault.config`
Applications can override the configuration file name. If the settings have never been changed, manually insert the following block of XML into the file within the `` tag:
```
```
To modify the settings, change the value for each setting in the XML.
### Available Settings
**CacheSize:** Maximum amount of memory (in MB) that SQL Race will use to cache raw data (default 1024).
!!! warning "Changing the settings below is not advisable. Contact MA for further support."
**PercentageToKeepFree:** The memory manager will attempt to keep at least this amount of cache available
(default 10).
**PercentageToFree:** Amount of the cache that should be freed when space needs to be made in the cache for
new data (default 20).
**MaximumSlotSize:** Maximum size of memory slot (in bytes) that can be cached. A smaller slot size may mean
less memory is wasted, but it also means that there will not be as much read-ahead benefit when loading the
data back into the cache. Setting this to 85000 or higher will likely result in excessive allocations on the LOH, so
it is recommended to keep below that (default 80000).
**MaximumTimeInMemoryBeforeFlushingInSeconds:** Amount of time data will be kept in memory before flushing
to disk (default 300).
**MaximumTimeInMemoryBeforeFreeingInSeconds:** Amount of time data will be kept in memory before the
memory is released (default 300).
**ParameterDataPoolingSize:** The maximum size (in MB) of the pool of ParameterValues objects used to fulfill
data requests. The objects are reused if possible, to reduce memory allocations and subsequent garbage
collection (default 512).
### When to change the settings
For optimal performance, increase the “CacheSize” setting, assuming your system has enough free memory. A
system with 16GB RAM should cope with the cache size increased to 2048. If ATLAS is used intensively with
significant data throughput and the messages still appear, increase it to 3072 or even 4096, assuming the
machine has enough available RAM.
| RAM Size (GB) | Recommended Cache Size (MB) |
|---------------|-----------------------------|
| 8 | 1024 |
| 16 | 2048 |
| 32 | 3072 |
| 64 | 4096 |
!!! tip
If you see messages like:
> “Not enough memory freed. Flushing 14.864 MB immediately. Consider increasing your cache size”
in the log file, the SQL Race cache is filling up too quickly. This results in excessive memory allocations and disk activity as ATLAS and SQL Race move more data around to stay within the limit.
## Cache Folder
Caching data is a technique used to improve the performance and efficiency of applications. It involves storing frequently accessed data in a temporary storage location, such as memory or disk, which is faster to access than the original source. This reduces the time and resources needed to fetch data repeatedly from the main storage.
Consider deleting the SQL Race cache folder improved performance, better disk space management, reduced startup time, and enhanced stability by resolving issues related to corrupted cache files.
## C# Garbage Collection
C# uses an automatic memory management system called garbage collection (GC), managed by the Common Language Runtime (CLR). When you create a new object, memory is allocated for it on the managed heap, a region of memory reserved for .NET applications.
The GC periodically checks for objects no longer in use by examining the application’s roots, such as static fields, local variables, and CPU registers. Unreachable objects are considered garbage, and their memory is reclaimed. After reclaiming memory, the GC compacts the remaining objects to reduce fragmentation and make memory
allocation more efficient.
### SQL Race and Memory Disposal
SQL Race doesn’t release memory immediately when a session is disposed. Instead, the garbage collector (GC) plays a crucial role in managing memory. Typically, resources are released after about 5 minutes. However, if the system requires memory sooner, the GC will release the resources earlier to accommodate the demand.
This approach helps optimize memory usage and ensures that the system runs efficiently.
### Force GC Option
Forcing garbage collection (GC) in ATLAS can have both benefits and drawbacks. On the positive side, it allows for immediate memory reclamation, which can be useful when you need to free up resources quickly. This can help optimize performance by reducing memory usage and preventing potential memory leaks.
However, there are also some downsides. Forcing GC can introduce performance overhead, as the process can be resource-intensive and may temporarily slow down the application. It can also lead to unpredictable behaviour, disrupting the normal GC cycle and potentially causing issues if not managed carefully.
{: style="max-width:50%;"}
!!! note
The Force GC feature was implemented to assist our developers in managing stress and benchmarking tasks, enabling quicker resource release between tests.
---
# SQL Race, SQLite & SSN2
This document provides a clear comparison between SQL Race Database, SQLite and SSN2, focusing on their roles within motorsport telemetry and general data management.
## SQL Race Database
SQL Race is a proprietary database access layer developed by Motion Applied, designed to handle high-frequency, structured telemetry data from motorsport environments. SQL Race sits on top of Microsoft SQL Server and provides a structured way to interact with telemetry and session data via SQL Race Database.
**Key Features:**
- Facilitates high-performance access to telemetry data stored in SQL Server.
- Supports multi-session synchronisation, composite session management, and statistical operations.
- Provides an API for programmatic access in Python, C#, MATLAB.
- Optimised for large datasets and high concurrency.
**Best For:**
- Trackside and engineering teams needing robust performance and analytics at scale.
- Scenarios requiring live telemetry and complex queries.
## SQLite
SQLite is a SQL database used for simpler, local data storage needs embedded within ATLAS. It does not require a separate server process. The only way to create SQLite session (SSNDB) is using an ATLAS Recorder (`Database Engine = SQLite`) or directly through SRMS (SQL Race Management Studio).
!!! tip
ATLAS uses SQLite cache for storing telemetry or recorded data as local (temporary) cache. Users can move the data from local cache (SQLite) to SSN2 or SQL Race Database (using SRMS) if the data needs to be persisted.
**Key Features:**
- Zero configuration – no server setup required.
- Portable and easy to integrate into standalone tools.
- Limited concurrency (single-writer, multi-reader).
**Best For:**
- Testing, or small-scale tools.
- Solo workflows or low-concurrency environments.
## SSN2
SSN2 is an ATLAS session file format that bundles session metadata and data streams together for portability.
**Key Features:**
- Stores session data in a single file.
- Ideal for sharing and archiving sessions.
- No separate filestream (unlike SQLite and SQL Race).
**Best For:**
- Offline workflows and data exchange between teams.
- Quick review of sessions without database infrastructure.
## Feature Summary
| Feature | **SQL Race Database** | **SQLite** | **SSN2** |
|---------------------|-----------------------------------------------|----------------------------------------|-----------------------------------|
| **Type** | SQL Race ontop of SQL Server | SQL Race ontop of SQL Server | File-based session format |
| **Concurrency** | High (multi-session, multi-user) | Limited (single-writer, multi-reader) | Single-user |
| **Performance** | Optimised for large, concurrent workloads | Good for small/local workloads | Basic (file read/write) |
| **Setup** | Requires SQL Server infrastructure | None (Embedded in ATLAS Client) | None |
| **Use Case** | Production-grade analytics, live telemetry | Lightweight local storage, prototyping| Sharing and archiving sessions |
| **File Stream** | Yes | Yes | No |
---
# Overview
Distribute live telemetry seamlessly across multi‑client workflows.
## [Open Data Package](open_streaming_architecture/index.md)
Provides open access to ATLAS data streams through standardised formats, enabling collaboration and integration with external systems and bespoke engineering tools.
### Key Functionality
- Modern microservice architecture
- Open telemetry data formats
- Lightweight processing libraries
- Virtual parameter calculation
## [Data Server Package](ads/index.md)
Enables high‑performance distribution of live telemetry across multiple clients via Ethernet or Wi‑Fi. Designed for distributed teams working collaboratively.
### Key Functionality
- Daisy‑chain server setups
- Integration with Control Limited workflows
- Multicast to multiple ATLAS clients
- Coverage cursor for data integrity checks
---
# Overview
ATLAS Data Server is a core component of the ATLAS ecosystem, providing a robust and scalable solution for storing and managing large volumes of telemetry data. It is designed to handle high-throughput data ingestion, efficient storage, and fast retrieval, making it ideal for applications that require real-time data processing and analysis.
## Key Features
1. **Daisy-Chaining**: Built for distributed teams, ATLAS Data Server's can be daisy chained together to accommodate distributed teams without having to compromise on live data requirements.
2. **High Availability**: Designed for fault tolerance, ensuring that data is always accessible even in the event of hardware failures.
3. **Data Integrity**: Implements strong data validation and integrity checks to ensure the accuracy and reliability of stored data.
5. **Integration with ATLAS Tools**: Seamlessly integrates with other ATLAS tools and services, enabling a unified data management experience.
## System Requirements
| Requirement | Minimum Supported | Recommended |
|------------------|----------------------------------|-------------------------------|
| Operating System | Windows 11 | Windows 11 |
| Memory | 1 GB | 8 GB or higher |
| Processor | Intel Core Duo 2GHz | Intel Core i7 Processor |
| Disk Space | HDD with 200 GB free disk space | High Capacity SSD 512GB or more |
## Licensing
ATLAS Data Server is available to users with Premium (1) or Data Platform variants of ATLAS. For more information contact the sales team [sales@motionapplied.com](mailto:sales@motionapplied.com).
{ .annotate }
1. Data Server Package is available to Premium users as an add-on.
---
# Getting Started
This guide walks you through installing and configuring the ATLAS Data Server (ADS) to manage and store telemetry data.
## Installation Steps
1. **Download the Installer**
Get the latest ATLAS Data Server installer from the [Motion Applied Portal](https://portal.motionapplied.com/portal/Downloads/Software#Standalone%20ADS).
2. **Run the Installer**
Launch the installer and follow the on-screen instructions.
3. **Configure the Server**
After installation, open the Standalone ADS application: `Start > All > McLaren Applied Technologies > Data Server`.
To add a SQLRace Database as a data source: `Tools > SQLRace > Connection Manager` and click **Add** to enter your SQL Server instance details.
!!! note
If you use ADS with SQLRace, install and configure SQLRace first. See the [SQLRace setup guide](../../store/sqlrace/installation.md).
## Data Server Setup
The steps below configure ADS through its interface, which is the right approach for a single
machine.
!!! tip "Setting up more than one machine?"
Every setting in this section can also be applied from an `ATLAS.ini` file, so a whole ADS
configuration can be deployed by copying one file and restarting ADS — no clicking through the
dialogs. See the [ATLAS.ini reference](atlas-ini.md).
### Server Settings File
The Server Settings file contains all of the setup information for ATLAS Data Server. It's important to spend time configuring these settings so that you don't need to repeat the process every time you open ATLAS Data Server.
1. Create a Server Settings File by creating a new file `AtlasServer.sbk` and saving it to a known location.
2. Go to `Tools > Options`
3. Under `Recording > General` find `Server Settings File` and enter the path to your `AtlasServer.sbk` file.
### Log File
The ATLAS Data Server creates a log file to record all events during operation. This log file is essential for troubleshooting and monitoring the server's performance.
1. Under `Recording > Logging (Debug)` find Log File Folder.
2. By default the log file is created in your Documents folder, at `McLaren Electronic Systems\ATLAS 9\log`. To update the location, change the path.
### Setting up IP addresses
1. Go to `Tools > Options > Data Server`
2. Find `Wide Band local address` and copy your IP address
3. Click OK to save and close the Options window.
### System Monitor Paths
Setting up the System Monitor paths allows ATLAS Data Server to locate the necessary configuration and data files for proper processing.
1. Go to `Tools > Options > System Monitor Folders`
2. In the System Monitor Base Folder field enter the path to the System Monitor project (.pgv).
3. In the Logging Configuration Folder field enter the path to the logging configuration folder (LogCfgs) inside of the System Monitor project.
4. Click OK to save and close the Options window.
---
# Recorders
In ADS, a “recorder” is the configured input/output endpoint that defines how data enters ADS (protocol/device/source) and how/where it gets stored/offloaded/distributed.
To access recorders, click `Setup > Add`
| Source | Description |
|--------|-------------|
| Ethernet Telemetry | Data is continuously uploaded while the car is connected via Ethernet. |
| Ethernet Wirelink | The contents of the data logging memory are uploaded when the car is connected via Ethernet. |
| RF Telemetry | Data is continuously uploaded while the car is transmitting Wide Band Telemetry. |
### General tab
The **General** tab is the first step in setting up ADS on your network.

Configure the following settings:
- Network parameters
- Status port for custom status monitoring services
- *(Optional)* Broadcast Streams for global telemetry and wirelink settings
### All tab
Use the **All** tab to define default session settings (details, export location, and so on) that apply to all future recorders on this ADS instance.

## Recorder types
### Dual Recorder
Dual Recorder writes to two different locations by duplicating the primary recorder.
To enable Dual Recorder:
1. Go to **Tools** > **Options** > **Recording** > **General**
2. Set **Dual Recorder** to `true`
3. Set the **Dual Recording SQL Race DB** to Recorder
4. Set the **Dual Recording SQL Race Recording Folder** path to where you want to save the data
5. Click **OK** to save

### DST Multi Source Recorder
A Multi Source Recorder automatically uploads data from available sources (Ethernet Telemetry, Ethernet Wirelink, or RF Telemetry). This ensures sessions use the best available data source at any time. Typically, Ethernet Telemetry operates in the pit, RF Telemetry on track, and Ethernet Wirelink offloads missed data.

Configure these options:
| Option | Description |
|--------|-------------|
| **Car number** | 1-4. Must match the value in System Monitor. |
| **Car** | Select a Car Definition from the drop-down list. |
| **Data source** | **DATA Lab Memory** (chassis parameters), **Burst Memory** (engine parameters), or **Burst and DATALab** (both). |
### TLM‑Px Multi Source Recorder
Before configuring the TLM-Px Recorder in ADS, The Telemetry Controller PC must be configured (VPN Agent Manager, Telemetry Controller Dashboard, and Telemetry Controller Interface). Once the Telemetry Controller is set up, follow these steps to configure the TLM-Px Multi Source Recorder in ADS:
1. Click `Setup > Add` and select TLM‑Px Multi Source Recorder
2. Select the car by unit IP (example: `172.27.92.26`)
3. In **Advanced settings** > **TLM‑Px** tab, set **Port number** to match the Control Telemetry Output UDP port(example: `4001`)
4. Configure other settings as needed
5. Click **OK** to save

---
# Options
To access the options dialog box, go to `Tools > Options` in ATLAS Data Server (ADS).

Every setting on this page is also a key that can be set in the `ATLAS.ini` file or written directly
to the registry, which is how an ADS installation is configured without using this dialog. The
`ATLAS.ini` key column below gives the name to use — see the
[ATLAS.ini reference](atlas-ini.md) for how the file works.
!!! note "Version note"
Settings, keys and defaults below reflect ADS 9.87.x. If you are running an older version, a
setting or its default may differ from what is shown here.
!!! tip "Reading the tables"
- **`ATLAS.ini` key** is both the INI key name and the registry value name. Unless stated
otherwise it lives under `[ADSAdvancedSettings]`.
- **Default** shows the ADS default, which for some settings differs from the ATLAS Viewer default
for the same key.
- **Restart** marks settings that only take effect after ADS is restarted.
- Settings shown as TRUE/FALSE here are written as `1`/`0` in `ATLAS.ini`.
## Recording Tab
The Recording tab of the Options dialog box contains advanced settings used to configure the
Recording system. Settings are grouped in the dialog under the headings used below.
### Coverage Cursor
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Coverage Minimum Percentage (0-100) | `CoverageMinimumPercentage` | `98` | | This option sets the minimum percentage of quads received before the Coverage Cursor moves to its next position. |
| Coverage Timeout (s) | `CoverageTimeout` | `60` | | The maximum time allowed for the Coverage Minimum Percentage to be reached. The Coverage Cursor moves to its next position when the Coverage Timeout is exceeded. |
| Coverage Cursor Span (%) | `CoverageCursorSpanPercentage` | `50` | | Controls how the coverage cursor is calculated on an incomplete block (under construction); not used for completed blocks. See the coverage cursor section for more info. |
| Quad sources excluded from coverage | `CoverageExcludedQuadSources` | `7` | | Comma-separated list of streams to exclude from the coverage cursor calculation. See the coverage cursor section for more info. |
| Plot Coverage Percentage | `PlotCoveragePercentage` | FALSE | | Plots coverage cursor % as a green line in the Data Server Statistic Panel; line height = percentage, time = delay. |
### Custom Decode DLL
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Custom quad buffer size in quads per source | `CustomQuadBufferSizeQuads` | `100000` | | Buffer size to cover payload when data quads are missing (used for custom data logging units). |
| Load decode DLL at Startup | `CustomQuadDecoderload` | FALSE | | When TRUE, loads the Decode DLL on application startup. |
| Unload decode DLL after recording | `CustomQuadDecoderUnload` | FALSE | | When TRUE, unloads the Decode DLL after recording. |
| Max quads generic recorder groups before sending | `GenericRecorderMaxQuadsInGroup` | `10` | | Limits max quads sent in one group so the generic recorder sends more often. |
### Data Server
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Data Servers | `WideBandDataServers` | Blank | | List of ATLAS Data Server names and corresponding ports in the form `{Server:Port}`. |
| Wide Band local address | `WideBandLocalAddress` | ANY | | Selects which network card is used for sending/receiving data; shows IPs of all NICs present. |
| Data Server connection timeout (ms) | `ServerConnectionRetryTime` | `20000` | | Time ATLAS waits for data from a Data Server before stopping recording. |
| Server auto-refresh frequency (ms) [0=disable] | `ServerAutoRefreshFreq` | `2000` | | Periodic refresh of current data servers shown in the Record dialog. |
| Server auto-refresh reply timeout (ms) | `ServerAutoRefreshReplyTimeout` | `100` | | Time before a data server is deemed offline when no activity is detected. |
| Timeout for searching for Data Servers (ms) | `SearchForServersTimeout` | `0` | | Time clients search for available Data Servers before timing out. |
| Server reply timeout [ms] | `ServerReplyTimeout` | `3000` | Yes | Time ATLAS waits for a reply from a Data Server. |
| Data Server Buffer size Mb | `WideBandBufferSize` | `20` | Yes | Size of client storage buffer for incoming data; should be large to avoid loss on poor networks. |
| Data Server Retries Enabled | `WideBandRetryMode` | FALSE | Yes | When TRUE, client may retry loading data from the network. |
### General
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Close record dialog after start/stop recording | `CloseRecDlgStopStart` | TRUE | | If TRUE, Record dialog closes when Start/Stop clicked; if FALSE, stays open. |
| Show Record Error Messages | `ShowRecordErrors` | FALSE | | When TRUE disables recording error pop-ups and writes errors to the Data Server log file. |
| Minimum Disk Space (MB) | `MinimumDiskSpace` | `500` | | If free disk space drops below this value, recording stops (with warnings beforehand). Minimum value is 500MB. |
| Enable Record to Disk | `EnableRecordToDisk` | TRUE | | When FALSE, data is only multicast to clients; no session is saved. |
| Quad sources excluded from lap trigger | `LapExcludedQuadSources` | Blank | | Rejects lap triggers sourced from listed streams (comma-separated). |
| Virtual Memory Block Size (KB) | `MemoryBlockSize` | `1024` | | Virtual memory slot size used by memory mapping in ATLAS. |
| Server Settings File | `SettingsFile` | `\AtlasServer.sbk` | Yes | Location of the server workbook (.sbk) holding Data Server configuration settings. |
| Auto Record connection check interval (ms) | `MonitorUnitStatusInterval` | `1000` | | Time ATLAS waits before stopping Automatic Recording. |
| Unload unused Pgvs on Start Recording | `ClearPgvCacheOnStartRec` | FALSE | | When TRUE, PGVs are removed from the cache when recording starts. |
| DTV Rename Cached Files | `RenameDtvCachedFiles` | FALSE | | When TRUE, cached DTV files include `_Cached` in the filename; set 'Unload Unused PGVs on Start Recording' if cached file not required. |
| Auto Increment Run Number | `AutoIncrementRunNumber` | FALSE | | Automatically increments Session Number name (e.g., R1, R2) for sequential recordings. |
| Hours to Delete Configs 0 = Disabled | `TimeInHoursToDeleteConfig` | `0` | | Automatically delete obsolete config files to optimize resources. |
| Enable 'still processing parameters' Dialog | `EnableAbortSavedParamsDlg` | TRUE | | Warns that parameter processing from config files is incomplete if recording ends prematurely. |
| Default disabled 'still processing parameters' to continue | `SavedParamsDlgDefaultContinue` | TRUE | | Sets which button the 'still processing parameters' dialog defaults to. When TRUE the default is to continue, so an unattended recording is not held up waiting for a response. |
| Automatic Multicast Address | `AutomaticMulticastAddress` | FALSE | Yes | When TRUE, server derives Multicast IP from last three integers of Local IP bind. |
| Setup Recorders From Registry | `SetupRecordersFromRegistry` | FALSE | Yes | Saves Recorder settings in registry rather than with a Workbook. |
| Temporary directory for recording files (default: blank) | `TempRecordingDirectory` | Blank | Yes | If set, session files are written here first and copied to the data path when recording stops. If blank, they are written directly to the data path. |
| Transmission timeslice (ms) | `TransmissionTimeslice` | `10` | | Period ADS sends multicast to the network (reducing may even peak load); 10ms should be minimum. |
| Delay Wirelink upload after recording (s) | `DelayWirelinkUpload` | `0` | | Delay (seconds) for data upload from unit at end of recording. |
| Auto-dismiss config search dialog | `AutoDismissConfigSearch` | TRUE | | When TRUE, config search box auto-closes. |
| Warn when config is missing | `WarnMissingConfig` | TRUE | | Warns when a configuration file needed for a recording cannot be found. |
| Send missing configs to clients | `SendMissingConfig` | TRUE | | Sends missing configuration files to clients that request them. |
| Recording event script | `RecordingEventScript` | Blank | | User-defined script called in a new process on recording events (LIVE_STARTED, LIVE_STOPPED, OFFLOAD_STARTED, OFFLOAD_STOPPED). |
| SQL Data Service Instance | `SQLDataServiceInstance` | Blank | Yes | Name of the SQL Data Service instance used for SQL Race recording. Leave blank to use the default instance. |
| DTV Offload Exclusion List | `DTVOffloadExclusionList` | Blank | Yes | Keywords specifying DTVs to exclude from offload (supports application-level and unit-specific formats). |
| PGV Exclusion List | `ADSLDFPGVExclusionList` | Blank | | Keywords specifying PGVs to exclude from processing at start of recording (application-level and unit-specific formats). |
| PGV Inclusion List | `PGVInclusionList` | Blank | | Keywords specifying PGVs to include in processing; inclusion list overrides exclusion list. |
| PGV Standalone List (Hex) | `PGVStandaloneList` | Blank | Yes | Hexadecimal keywords identifying PGVs to be treated as standalone. |
| Auto Merge Option | `EnableAutoMerge` | Disabled | | Drop-down: Disabled (sources only from .cfg), Maximum (all sources added), Minimum (one parameter added but merge performed on all sources; not selectable in ADS). |
| Process Weather.prm | `ProcessWeatherPgv` | FALSE | | Processes `Weather.prm` during recording. |
| Process Scalar | `ProcessScalar` | FALSE | | Processes scalar parameters during recording. |
| Enable Pre-Record Config Transfer | `EnablePreRecordConfigTransfer` | TRUE | Yes | When TRUE, allows sending config files when not recording. |
| Pre-Record Config Transfer Boost Time (s) | `PreRecordConfigTransferBoostTime` | `10` | Yes | Duration (seconds) that config send rate increases to boost rate. |
| Pre-Record Config Transfer Rate (KBps) | `PreRecordConfigTransferRate` | `50` | Yes | Raised config send rate used during boost time. |
| Enable New Unique Filter | `EnableNewUniqueMethod` | FALSE | Yes | Enables new unique filter and disables Missing Data Upload; allows Quad ID to wrap while still ensuring uniqueness on network. |
| Enable dual recording | `EnableDualRecording` | FALSE | Yes | Enables the out-of-process dual recorder, which writes a second copy of the recording via a separate process. |
| Dual recording end point | `DualRecordingEndPoint` | `[::1]:9798` | Yes | Endpoint of the dual recording process, in `host:port` form. The default is IPv6 loopback. |
| Dual recording SQL Race DB | `DualRecordingDB` | Blank | Yes | SQL Race connection used for the dual recording. |
| Dual recording SQL Race Recording Folder | `DualRecordingSqlRaceRecordingFolder` | `\Server` | Yes | Folder the dual recorder writes SQL Race session files to. |
| Dual recording server listener IP | `DualRecordingServerListenerIP` | `127.0.0.1` | Yes | Local IP address the dual recording listener binds to. |
| Dual recording server listener port | `DualRecordingServerListenerPort` | `6800` | Yes | Port the dual recording listener binds to. |
| Enable FTP download | `EnableFTPDownload` | FALSE | | Enables downloading data from a logging unit over FTP. |
| Enable Bridge Service | `EnableRemoteDataFeed` | FALSE | Yes | Master switch for the Bridge Service. When disabled, ADS makes no Bridge Service connection and the status indicator stays grey. |
| Bridge Service Endpoint | `RemoteDataFeedEndpoint` | `[::1]:9697` | Yes | Address of the Bridge Service in `host:port` form. Square brackets are required around an IPv6 literal; the default is IPv6 loopback. |
| Local Bridge Service | `LocalRemoteDataFeed` | FALSE | Yes | When enabled, ADS starts and stops the Bridge Service process itself. When disabled, it connects to a Bridge Service that is already running and leaves it running on exit. |
| *(not shown in dialog)* | `TempSqlRaceRecordingDirectory` | `\Server` | | Folder used for in-progress SSN2 recordings. Set automatically from `Temporary directory for recording files`, or the data folder, and not editable in the dialog. *Not editable in the dialog.* |
### Handshake Server
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Handshake Minimum Time [ms] | `HandshakeMessageTimeoutMin` | `100` | | Minimum timeout for handshake message from data server to car. |
| Handshake Maximum Time [ms] | `HandshakeMessageTimeout` | `200` | | Maximum timeout for handshake message from data server to car. |
| Handshake Message Queue Length | `HandshakeMessageQueueLength` | `2` | | Maximum message queue length awaiting transmission. |
| Handshake Message Size | `HandshakeMessageSize` | `640` | | Must match message size supported by embedded system. |
| Use Low Rate Message | `HandshakeMessageUseLowRateMsg` | FALSE | | When TRUE, uses compressed handshaking messages. |
| Low Rate Maximum Time [ms] | `HandshakeMessageLowRateTimeout` | `2000` | | Maximum time between low-rate handshaking messages. |
| Low Rate Maximum Message Size | `HandshakeMessageLowRateSize` | `18` | | Maximum size of low-rate handshaking messages. |
### Advanced Data Feed
Settings for the Advanced Data Feed, which publishes recorded data to Kafka.
All of these require a restart.
| Setting | `ATLAS.ini` key | Default | Description |
|---|---|---|---|
| Enable Advanced Data Feed Producer | `ADFProducerEnable` | FALSE | Enables the Advanced Data Feed Kafka producer. |
| client.id | `client.id` | `ADS` | Client identifier presented to the Kafka brokers. |
| metadata.broker.list | `metadata.broker.list` | Blank | Comma-separated list of Kafka brokers to connect to. Required when the producer is enabled. |
#### Kafka client properties
The remaining 73 settings in this group are **librdkafka** producer properties. The key
name *is* the librdkafka property name, and the value is passed to the Kafka client
unchanged, so the librdkafka configuration reference is the authority on what each one
does. They are shown in the dialog but cannot be edited there — set them through
`ATLAS.ini` or the registry if you need to change them.
| `ATLAS.ini` key | Default |
|---|---|
| `builtin.features` | Blank |
| `message.max.bytes` | `1000000` |
| `receive.message.max.bytes` | `100000000` |
| `metadata.request.timeout.ms` | `60000` |
| `topic.metadata.refresh.interval.ms` | `300000` |
| `topic.metadata.refresh.fast.cnt` | `10` |
| `topic.metadata.refresh.fast.interval.ms` | `250` |
| `topic.metadata.refresh.sparse` | TRUE |
| `topic.blacklist` | Blank |
| `debug` | Blank |
| `socket.timeout.ms` | `60000` |
| `socket.blocking.max.ms` | `100` |
| `socket.send.buffer.bytes` | `1048576` |
| `socket.receive.buffer.bytes` | `1048576` |
| `socket.keepalive.enable` | FALSE |
| `socket.max.fails` | `3` |
| `broker.address.ttl` | `1000` |
| `broker.address.family` | `any` |
| `reconnect.backoff.jitter.ms` | `0` |
| `statistics.interval.ms` | `0` |
| `log_level` | `6` |
| `log.thread.name` | FALSE |
| `log.connection.close` | TRUE |
| `internal.termination.signal` | `0` |
| `quota.support.enable` | FALSE |
| `protocol.version` | `0` |
| `security.protocol` | `plaintext` |
| `ssl.cipher.suites` | Blank |
| `ssl.key.location` | Blank |
| `ssl.key.password` | Blank |
| `ssl.certificate.location` | Blank |
| `ssl.ca.location` | Blank |
| `sasl.mechanisms` | `GSSAPI` |
| `sasl.kerberos.service.name` | `kafka` |
| `sasl.kerberos.principal` | `kafkaclient` |
| `sasl.kerberos.kinit.cmd` | `kinit` |
| `sasl.kerberos.keytab` | Blank |
| `sasl.kerberos.min.time.before.relogin` | `60000` |
| `group.id` | Blank |
| `partition.assignment.strategy` | `range,roundrobin` |
| `session.timeout.ms` | `30000` |
| `heartbeat.interval.ms` | `1000` |
| `group.protocol.type` | `consumer` |
| `coordinator.query.interval.ms` | `600000` |
| `queued.min.messages` | `100000` |
| `queued.max.messages.kbytes` | `1000000` |
| `fetch.wait.max.ms` | `100` |
| `fetch.message.max.bytes` | `1048576` |
| `max.partition.fetch.bytes` | `1048576` |
| `fetch.min.bytes` | `1` |
| `fetch.error.backoff.ms` | `500` |
| `offset.store.method` | `broker` |
| `queue.buffering.max.messages` | `100000` |
| `queue.buffering.max.ms` | `1000` |
| `message.send.max.retries` | `2` |
| `retry.backoff.ms` | `100` |
| `compression.codec` | `none` |
| `batch.num.messages` | `1000` |
| `delivery.report.only.error` | FALSE |
| `request.required.acks` | `1` |
| `request.timeout.ms` | `5000` |
| `message.timeout.ms` | `300000` |
| `produce.offset.report` | FALSE |
| `auto.commit.enable` | TRUE |
| `enable.auto.commit` | TRUE |
| `auto.commit.interval.ms` | `60000` |
| `auto.offset.reset` | `largest` |
| `offset.store.path` | Blank |
| `offset.store.sync.interval.ms` | `-1` |
| `offset.store.method` | `file` |
| `consume.callback.max.messages` | `0` |
| `opaque` | FALSE |
| `ADFCompleteSessionsTimeout` | `60000` |
### Live Data Feed
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| ldf.metadata.broker.list | `LiveData2ConnectionBrokerList` | Blank | Yes | Comma-separated list of Kafka brokers used by the Live Data Feed connection. |
| Enable Live Data Feed | `ADSLDFEnable` | FALSE | Yes | When TRUE, data can be transferred via live data feed. |
| Send All Data | `ADSLDFSendAllData` | FALSE | | Sends all data over the Live Data Feed rather than only the requested subset. |
| Live Data Feed Retrieval Path | `ADSLDFFilePath` | `\McLaren Electronic Systems\ATLAS 9\LDS` | | Location used to store intermediate (LDR) files when using LDF. |
### Logging (Debug)
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Log File Folder | `LogFileFolder` | `\McLaren Electronic Systems\ATLAS 9\log` | | Location for log files. |
| Raw Data Logging | `RawDataLogging` | FALSE | | Saves raw telemetry data during recording to .raw and .raw_tm files (for diagnostics). |
| Raw Data Root Folder | `RawDataRootFolder` | Blank | | Location for files created by Raw Data Logging. |
| Raw Data Logging [VTS] | `RawVTSDataLogging` | FALSE | | Saves VTS raw data during recording to .raw and .raw_tm files (for diagnostics). |
| Performance Statistics | `PerformanceCounterStats` | FALSE | | When TRUE, creates performance log file (developer analysis/debugging). |
| Message log level (for debugging) | `MessageLogSetting` | Not Logging | | Level of diagnostic message logging. Intended for support and development use. |
| Message log file size (MB) | `MaxLogFileSizeMB` | `5` | Yes | ATLAS log file size limit (0MB = infinite; new file created when limit reached). |
### Offload
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Enable Update Progress On Clients (3 Source) | `WireLinkUpLoadStatusBroadcast` | TRUE | | Enables client update progress bar on ADS dialog during data upload. |
| Enable Multicast for Wirelink (3 Source) | `WireLinkMulicastControl` | TRUE | | When TRUE, all three recording sources enabled in ADS Advanced Multi Source setup (may hinder network performance). |
| Exclude Offload Streams | `ExcludeOffloadStreams` | Blank | | Prevent ADS from offloading specific unit streams (comma-separated list). Overrides may apply with Telemetry Streams setting. |
| Enable Reverse Upload | `EnableReverseUpload` | FALSE | | Uploads missing data in reverse order, newest first. |
| Apps To Exclude From Clear Max/Min/Errors | `ExcludeAppsFromClear` | `CBT610;CBR610` | | Semicolon-separated list of applications excluded when max/min values and errors are cleared on a logging unit. |
| Produce Encrypted Export Files | `ProduceEncryptedExportFiles` | FALSE | | Encrypts export files produced at the end of a recording. |
### Remote Data Server
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Enable Remote Data Server | `ADSRDREnable` | FALSE | | When TRUE, data can be transferred via the remote data server. |
| Remote Data Server Retrieval Path | `ADSRDRFilePath` | `\McLaren Electronic Systems\ATLAS 9\RDS` | | Location used to store intermediate (RDR) files when using RDS. |
| RDS Write to Log File | `RDS Write to Log File` | TRUE | | When TRUE, RDS diagnostics written to an RDS log file in the main ATLAS log folder. |
| RDS Logging level | `RDSMessageLogSetting` | Minimum | Yes | Verbosity of Remote Data Server diagnostic logging. |
| Auto delete PARTIAL Sessions | `ADSAutoDeletePartialSSN` | TRUE | | After playback when .ssn is created, delete PARTIAL live session file (when unlocked). |
| Enable RDR Transfer During Live (Master Only) | `ADSRDRTransferDuringLive` | FALSE | | Enables ADS to transmit RDR data simultaneously with live recording if spare bandwidth available. |
| Enable Multi-Session RDR | `ADSRDREnableMultiSession` | FALSE | | Allows the Remote Data Server to transfer more than one session at a time. |
| Enable VTS Session Save | `EnableRdsSaveVtag` | FALSE | | Saves vTAG session data received over the Remote Data Server connection. |
### Telemetry
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Telemetry Guard Time (s) | `TelemetryGuardTime` | `0` | | Reject data if timestamp difference between packets exceeds this value. |
| Telemetry Guard Filter Length | `TelemetryGuardSynchronizationLength` | `10` | | Telemetry Guard synchronization length. |
| Telemetry Guard Quad Range Limit 0 = Disabled | `TelemetryGuardQuadRange` | `0` | | Maximum allowable gap between sequential Quad IDs within a stream. |
| Live Telemetry Timeout 0 = Disabled | `LiveTelemTimeout` | `50` | | For Marelli DST Receiver only: time after which ATLAS stops recording if no live data received (overridden by active Ethernet recorders). |
| Session Completion Timeout 0 = Disabled | `SessionTimeout` | `0` | | Time (seconds) to stop recording after last data sample; 0 disables. |
| Enable VTS Session Completion Timeout | `VTSSessionTimeoutEnable` | TRUE | | Allows VTS Recorder to timeout per Session Completion Timeout; FALSE overrides timeout. If timeout is 0, this has no effect. |
| Telemetry Streams To Complete Missing Offload | `TelemetryStreams` | Blank | | Streams required for missing telemetry uploads before closing (comma-separated); uploaded first; live record status cleared after last stream completes; overrides Exclude Offload Streams. |
| Transmitter Status Timeout 0 = Disabled | `CBTStatusTimeout` | `0` | | Time (seconds) that a status from a CBR600 is valid; after this time, last status ignored until a new one arrives. |
| Sequence number anti-wrap time (hours) 0 = Disabled | `AntiWrapTime` | `0` | | Threshold delta time where sequence numbers auto-unwrap; applies only to current instance (forwarded data unaffected). |
| DST Interface Version | `DSTInterfaceVersion` | 3 | Yes | Version of the Magneti Marelli DST receiver interface to use. Must match the receiver in use. |
| SCS Logging Control Streams | `ScsTelemetryLoggingControlStreams` | `1,2` | | Comma-separated list of streams used for Standard Communication System logging control. |
### Unit Comms
| Setting | `ATLAS.ini` key | Default | Restart | Description |
|---|---|---|---|---|
| Ethernet Receive Timeout (ms) | `EthernetReceiveTimeout` | `500` | | Time ATLAS waits before retrying a receive message. |
| Ethernet Send Timeout (ms) | `EthernetSendTimeout` | `500` | | Time ATLAS waits before retrying a send message. |
| Ethernet retries | `EthernetRetries` | `1` | | Number of times ATLAS retries a message before aborting and showing a warning. |
| Ethernet upload message interval timeout (ms) | `EthernetUploadMsgTimeout` | `3` | | Time before Quad Ethernet Telemetry data is re-requested during an upload (auto-extended if data receipt detected beyond timeout). |
| Ethernet upload message extended timeout (ms) | `EthernetUploadExtendTimeout` | `500` | | Time ATLAS waits before Quad Ethernet Telemetry offload times out. |
| Ethernet offload connection retries | `EthernetUploadConnectionRetries` | `10` | | Number of reconnection attempts during offload if connection is lost. |
| Ethernet Minimum UDP Missing Request command size Limit | `EthernetMinimumMissingRequestLimit` | `512` | | Minimum command size when requesting missing data to avoid IP fragmentation issues (steps down from maximum when timeouts occur). |
| Ethernet Maximum UDP Missing Request command size Limit | `EthernetMaximumMissingRequestLimit` | `1472` | | Maximum command size when requesting missing data; may need adjustment if VPN introduces fragmentation. |
| Ethernet upload config unique response | `EthernetUploadCfgResponse` | FALSE | | Setting must match client-specific BIOS configurations. |
| Enable missing data upload | `EnableMissingDataUpload` | TRUE | | When TRUE, only data found to be missing is uploaded; when FALSE, all data uploaded regardless. |
| Ethernet Buffer Size (MB) | `EthernetBufferSize` | `5` | Yes | Size of local cache used for Direct Ethernet Wirelink. |
| Default Timeout (ms) | `DefaultTimeout` | `200` | Yes | Default timeout applied to unit communications that have no more specific timeout. |
| Enable Unit Status Message | `EnableUnitCfgStatusMessage` | TRUE | Yes | Enables the configuration status message sent to logging units. |
## Recorder Folders Tab
The Recorder Folders tab sets the paths ADS uses for configurations and parameter files. These keys
live under **`[Preferences]`**, not `[ADSAdvancedSettings]`.
| Setting | `ATLAS.ini` key | Description |
|---|---|---|
| System Monitor 7 base folder | `SystemMonitor7BaseFolder` | Path where System Monitor files are stored. Multiple paths can be separated with semicolons. |
| Logging configuration folder | `ConfigFolder` | Path where ADS writes logging configuration files. |
| Ancillary parameters folders | `AncilliaryParametersFolders` | Paths where logging configurations created in System Monitor are stored, semicolon-separated. Note the doubled `l` in the key name. |
| Parameter unlock list path | `ParameterUnlockListDir` | Path ADS searches for parameter unlock lists. Also passed to SQL Race as its unlock list search path. |
| Custom PGV path | `CustomPGVFolder` | Path where the LDF recorder stores received PGV files. |
| Cars database file | `CarDatabaseFile` | Path and file name of the car definitions file. Stored under `HKCU\Software\McLaren Electronic Systems`, not under the ATLAS 9.0 key, so it cannot be set from `ATLAS.ini`. |
Other `[Preferences]` paths that ADS uses but that are not on this tab — including `DataFolder`,
`WorkbookFolder` and `LocalFolder` — are listed in the
[ATLAS.ini reference](atlas-ini.md#preferences).
## Slave ADS Connection Tabs
Two tabs, **Slave ADS Connection 1** and **Slave ADS Connection 2**, configure outgoing connections
to slave data servers.
!!! note "Licence gated"
These tabs only appear if the **Remote Data Server** licence option is present. Without it, both
connections are forced off regardless of what is configured.
In the keys below `N` is `0` for the first tab and `1` for the second. The two connections must not
use the same port. `Allow connection` cannot be changed while a recording is in progress.
| Setting | `ATLAS.ini` key | Default (tab 1 / tab 2) | Description |
|---|---|---|---|
| Allow connection | `SlaveADSConnectionNEnable` | FALSE | Enables this slave connection. |
| Port | `SlaveADSConnectionNPort` | 5010 / 5011 | Port used for the connection. |
| Auto data rate | `SlaveADSConnectionNAutoRate` | TRUE | Adjusts the data rate automatically rather than using the fixed maximum. |
| Max data rate | `SlaveADSConnectionNMaxRate` | 500 | Maximum data rate in KB/s. |
| Min data rate | `SlaveADSConnectionNMinRate` | 0 | Minimum data rate in KB/s. |
| Compression | `SlaveADSConnectionNCompression` | FALSE | Compresses data sent over the connection. |
| Send VTAG data | `EnableVtagDataRdsConnectionN` | FALSE | Includes vTAG data in the connection. |
| Quad sources excluded | `SlaveADSQuadSourceNExcluded` | Blank | Comma-separated list of streams to exclude from this connection. |
| *(no control)* | `SlaveADSConnectionNRetransmission` | FALSE | Enables retransmission of lost data. |
| *(no control)* | `SlaveADSConnectionNMaximumSize` | 100 | Maximum block size before sending. |
| *(no control)* | `SlaveADSConnectionNMaximumTime` | 1 | Maximum time to wait before sending a partial block. |
## Live Data Feed Connection Tab
Configures the Live Data Feed connections. The broker list for the current connection is on the
Recording tab as `LiveData2ConnectionBrokerList`; the remaining keys are on this tab.
| Setting | `ATLAS.ini` key | Default | Description |
|---|---|---|---|
| Allow | `LiveData2ConnectionEnable` | FALSE | Enables the Live Data Feed connection. |
| Send VTAG data | `LiveData2SendVtagData` | TRUE | Includes vTAG data in the feed. |
| Data rate | `LiveData2ConnectionMaxRate` | Blank | Maximum data rate in KB/s. Blank applies no limit. |
| Quad sources excluded | `LiveData2ConnectionStreamsExcluded` | Blank | Comma-separated list of streams to exclude. |
!!! warning "Deprecated connections"
The two numbered connections below are labelled **Deprecated** in ADS and are retained only for
existing installations. Use the connection above for new configurations.
| Setting | `ATLAS.ini` key (`N` = 0 or 1) | Default (1 / 2) | Description |
|---|---|---|---|
| Allow | `LiveDataConnectionEnableN` | FALSE | Enables this legacy connection. |
| Port | `LiveDataConnectionPortN` | 5012 / 5013 | Port used for the connection. |
| Data rate | `LiveDataConnectionMaxRateN` | 150 | Maximum data rate in KB/s. |
| Send VTAG data | `LiveDataConnectionNSendVtagData` | TRUE | Includes vTAG data in the feed. |
| Quad sources excluded | `LiveDataConnectionStreamsExcludedN` | Blank | Comma-separated list of streams to exclude. |
| *(no control)* | `LiveDataConnectionMinRateN` | 50 | Minimum data rate in KB/s. |
| *(no control)* | `LiveDataConnectionCompressionN` | FALSE | Compresses data sent over the connection. |
| *(no control)* | `LiveDataConnectionAutoRateN` | FALSE | Adjusts the data rate automatically. |
| *(no control)* | `LiveDataConnectionEnableRowData` | TRUE | Includes row data in the legacy feed. |
!!! note
`LiveDataConnectionNSendVtagData` follows a different pattern to the other keys — the index comes
immediately after `LiveDataConnection`, giving `LiveDataConnection0SendVtagData`.
## Library Tab
Sets the function libraries loaded by ADS, and whether session constants are sent to clients.
| Setting | `ATLAS.ini` key | Description |
|---|---|---|
| Use server constants | `SendSessionConstantsToClients` | Sends session constants from the server to connected clients. Lives under `[AtlasDataServer]`. |
| Library list | `Defaults`, `DefaultsAttrib`, `Order`, `DefaultsType` | Function library entries, under the `ADSLibrary` key. ADS uses its own library key, separate from the ATLAS Viewer's. |
!!! note
The library list values are multi-string registry values and **cannot** be set from `ATLAS.ini`.
Configure them in the interface, or write them to the registry as `REG_MULTI_SZ`.
## Decode DLLs Tab
The Decode DLL tab is used to allocate customer-created DLLs to a data stream. A total of 15 data
streams are available.

| Setting | `ATLAS.ini` key | Description |
|---|---|---|
| Decode DLL Path | `CustomQuadDecoderFilepath` | Enter the full path and filename of the Decode DLL, or browse to locate it. The installer seeds this with the bundled `CustomDLLs\AtlasApiDecoder.dll`. |
Related settings are on the Recording tab under [Custom Decode DLL](#custom-decode-dll).
## System Monitor Folders Tab
The System Monitor Folders tab controls how ADS works with System Monitor configurations. These keys
are under **`[Preferences]`** and are the same values as the
[Recorder Folders tab](#recorder-folders-tab).
| Setting | `ATLAS.ini` key | Description |
|---|---|---|
| System Monitor 7 base folder | `SystemMonitor7BaseFolder` | Sets the path where System Monitor files are stored. Multiple paths can be separated with a semi-colon. |
| Logging configuration folder | `ConfigFolder` | Sets the path where ADS writes Logging configuration files. File structure must be: `…ATLAS V8\Config\Logging\AutoConfig` |
| Car definitions file | `CarDatabaseFile` | Sets the path and file name of the Car definitions file that defines network communication. |
| Ancillary Parameters Folder | `AncilliaryParametersFolders` | Sets the path where Logging Configurations created in System Monitor are stored. |
| Parameter Unlock List Path | `ParameterUnlockListDir` | Sets the path where ADS searches for Parameter Unlock Lists. |
| Custom PGV Path | `CustomPGVFolder` | Sets the path where the ADS LDF Recorder stores received PGV files. |
## Settings with no dialog control
These are read from `[ADSAdvancedSettings]` but have no control in the Options dialog. They are
included for completeness — most are internal or legacy, and should only be changed on advice from
support.
| `ATLAS.ini` key | Group | Default | Description |
|---|---|---|---|
| `WideBandInfoPort` | Data Server | 9696 | UDP port used to broadcast to and discover data servers. |
| `EnableADSTestMode` | General | FALSE | Enables ADS test mode. |
| `NarrowBandDataServer` | General | Blank | Legacy narrow band data server list. |
| `NarrowBandSequenceWindowLength` | General | 4 | Legacy narrow band sequence window length. |
| `NarrowBandWindowLength` | General | 10000 | Legacy narrow band window length. |
| `PreciseLapTimes` | General | TRUE | Enables precise lap time calculation. |
| `EnableAddFixedParameters` | General | TRUE | Adds fixed parameters to recorded sessions. |
| `EnableEthernetQuadTelemetry` | General | TRUE | Enables quad Ethernet telemetry. |
| `HandshakeMessagePLMN` | Handshake Server | 23415 | PLMN provider code used in handshake messages. |
| `HandshakeMessageTechnology` | Handshake Server | 2 | Network technology type used in handshake messages. |
| `HandshakeMessageUseSlowRowIP` | Handshake Server | FALSE | Uses the slow row for the IP address in handshake messages. |
| `broker.version.fallback` | Advanced Data Feed | `0.9.0.0` | Kafka broker version assumed when it cannot be determined. |
| `ADSSyncRDRFolderCheck` | Remote Data Server | TRUE | Checks the RDR folder synchronously. |
| `RDRPerformanceCounterSubsample` | Remote Data Server | 16 | Subsampling factor for RDR performance counters. |
| `AutoTelemTimeout` | Telemetry | 20 | Timeout used by automatic telemetry detection. |
| `EnableDstParameters` | Telemetry | FALSE | Enables DST-specific parameters. |
| `ScsLoggingControlCount` | Telemetry | 10 | Standard Communication System logging control count down. |
## Settings no longer in this dialog
If you are working from an older document or an existing `ATLAS.ini`, note that the following are
**not** ADS Options settings:
- **SQL Race logging and performance counters** — `SQL Race Logging Level`, `SQL Race Log File Path`,
`SQL Race Logging Period`, `Enable SQL Race Perf Counters`,
`Enable SQL Race Perf Counters Log to File`, `Enable SQL Race Background Metrics` and
`SQL Race Cache Size` are no longer registered as ADS settings and have no effect if set. Configure
SQL Race logging through SQL Race itself.
- **Session File Type** — chosen per recording in the Record dialog destination, not here.
- **Viewer-only settings** — `Wideband Min Lap Time`, `Record Telemetry Data From Start`,
`Record Only Live Data`, `Unload Session on Start Recording`, `Save Client Config File to Disk`,
`Use Only the Highest Rate Continuous Channel in Merging`,
`Regenerate Merged Channels at the end of a Recording` and `PGV Request Timeout` exist in the ATLAS
Viewer but are not shown or used by ADS.
## See also
- [ATLAS.ini reference](atlas-ini.md) — setting any of these keys from a file, for scripted deployment
- [Recorders](recorders.md) — recorder types and their settings
- [RDS](rds.md) — Remote Data Server configuration
---
# ATLAS.ini File
`ATLAS.ini` is a plain text file that sets ATLAS Data Server (ADS) configuration without using the
GUI. Any setting normally changed in `Tools > Options` can be written into this file instead, which is what makes a scripted or automated ADS deployment possible. Values supplied by the file also become read-only in the interface, so a configuration can be applied consistently and left locked.
!!! note "Version note"
Keys, defaults and behaviour on this page reflect ADS 9.87.x. If you are running an older
version, a default may differ from what is shown here.
## Why use ATLAS.ini
Configuring ADS through the GUI is fine for a single machine, but it does not scale and it cannot be scripted. `ATLAS.ini` solves three problems:
- **Repeatable deployment.** One file, copied to each machine, replaces a long click-through of the Options dialog.
- **Locked-down settings.** A setting that comes from `ATLAS.ini` is displayed greyed out and cannot be edited or overwritten from the interface. This is useful for values that must not be changed.
- **Multi-user and service accounts.** The ADS installer writes its default settings under
`HKEY_CURRENT_USER` for the installing user only. If ADS runs under a different account, those
defaults never materialise.
## Where ATLAS.ini lives
By default ADS looks for the file at:
```
McLaren Electronic Systems\ATLAS 9\Atlas.ini
```
Two things about this path:
- **It is per-user.** The file must be in the Documents folder of the account ADS runs under, not the account that installed it.
- **Folder redirection applies.** If Documents is redirected — most commonly by OneDrive Known Folder
Move — the path follows the redirect, for example
`C:\Users\...\McLaren Electronic Systems\ATLAS 9\Atlas.ini`.
This PowerShell snippet writes the file to the correct location for the current user:
```powershell
$dir = Join-Path ([Environment]::GetFolderPath('MyDocuments')) 'McLaren Electronic Systems\ATLAS 9'
New-Item -ItemType Directory -Force $dir | Out-Null
@'
[ADSAdvancedSettings]
EnableRemoteDataFeed = 1
'@ | Out-File (Join-Path $dir 'Atlas.ini') -Encoding ascii
```
### Moving the file
The location can be changed with a registry value that holds the full path **including the file
name**:
| Registry key | Value | Type |
|---|---|---|
| `HKEY_CURRENT_USER\Software\McLaren Electronic Systems\ATLAS\9.0\Preferences` | `ATLASIniFile` | String |
In the ATLAS Viewer this is exposed as `Tools > Options > Standard`. ADS has no equivalent control, so set it in the registry directly.
!!! warning "Two limits on relocating the file"
`ATLASIniFile` is read from the registry only — it cannot be set from inside `ATLAS.ini`, because the file has not been located at the point it is needed.
A small number of settings are read very early during start-up, before the relocation is applied
— including `RemoteDataFeedEndpoint` and the Bridge Service log path. If you relocate
`ATLAS.ini`, those two are still taken from the default location. Unless you have a reason to move the file, leave it at the default path; if you must move it, set the Bridge Service values in the registry instead.
Unlike the ATLAS Viewer, **ADS does not accept an `.ini` path on the command line**. The default
location and `ATLASIniFile` are the only two options.
## How overrides are applied
### Precedence
For every setting ADS reads, the order is:
1. **`ATLAS.ini`** — if the section and key are present, this value is used.
2. **Registry** — otherwise the value under the ADS registry key is used.
3. **Built-in default** — otherwise the shipped default is used, and is written into the registry.
A value that comes from `ATLAS.ini` is never copied into the registry, and ADS never writes back to`ATLAS.ini`.
### Settings from the file are read-only
When a setting is supplied by `ATLAS.ini`, ADS marks it read-only. In `Tools > Options` it appears
greyed out, and attempts to change it are discarded. This is the quickest way to confirm a key has
been picked up.
### Changes require a restart
`ATLAS.ini` is read once per process and cached until ADS exits. **Editing the file while ADS is
running has no effect** — restart ADS to apply changes.
Separately, many individual settings are themselves flagged as requiring a restart; these are marked in the [Options reference](options.md).
## File syntax
`ATLAS.ini` is a standard Windows INI file, read with the Win32 private profile functions. The rules follow from that.
### Sections and keys
A section name is the **registry sub-key**, relative to `HKEY_CURRENT_USER\Software\McLaren Electronic Systems\ATLAS\9.0`. A key name is the **registry value name**. So this file:
```ini
[ADSAdvancedSettings]
LogFileFolder = D:\ATLASLogs
```
sets the same thing as the registry value `LogFileFolder` under `HKCU\Software\McLaren Electronic Systems\ATLAS\9.0\ADSAdvancedSettings`.
- Section and key names are case-insensitive.
- Nested registry keys use a backslash in the section name, for example
`[ADSAdvancedSettings\RecorderSettings]`.
- A section header may appear only once per file. Repeating it means the later block is ignored.
- Comments start with a semicolon (`;`). A hash (`#`) is **not** a comment character and will be
read as part of a value.
- Whitespace around `=` is trimmed, and surrounding double quotes are stripped.
### Value types
| Type | How to write it |
|---|---|
| String | Verbatim text, up to 1024 characters. Do not quote paths. |
| Number | Decimal only. Hexadecimal (`0x…`) and digit separators are not accepted. |
| Boolean | `1` or `0`. |
!!! warning "`true` and `false` do not work"
Boolean settings must be written as `1` or `0`. The interface displays them as True/False, but
the file is parsed numerically — `true` is read as `0`, silently giving you the opposite of what you intended.
Save the file as **ANSI/ASCII**, not UTF-16. In PowerShell use `-Encoding ascii`; `Out-File` and `>` default to UTF-8, and `Set-Content` defaults to the system code page.
### Values that cannot be set from the file
- **`-1` and `-2`.** These two values are indistinguishable from "key not present", so a setting
written as `-1` is ignored and the registry or default value is used instead. Where a setting
needs to be disabled, use the documented disable value (usually `0`).
- **Multi-string values.** The function library lists under `ADSLibrary` (`Defaults`, `Order`,
`DefaultsAttrib`) are `REG_MULTI_SZ` and have no INI representation. Set them in the registry.
- **Binary values.** Recorder session details are stored as a binary blob (see
[Recorder settings](#adsadvancedsettingsrecordersettings)).
- **Root-level values.** A handful of values live directly under the `ATLAS\9.0` key rather than in a sub-key, and cannot be reached from the file because a section name is required.
- **`HomeFolder`.** Read from the registry only.
- **Environment variables.** There is **no** expansion of `%USERPROFILE%` or any other variable —
write literal absolute paths. Older sample files that use `%USERPROFILE%` are incorrect.
## Sections reference
ADS reads four sections.
| Section | Contains | Gate |
|---|---|---|
| `[Preferences]` | Folder and file paths | — |
| `[ADSAdvancedSettings]` | Everything in `Tools > Options` | — |
| `[AtlasDataServer]` | `Setup > Configure Interfaces` network settings | `InitializeFromRegistry = 1` |
| `[ADSAdvancedSettings\RecorderSettings]` | Recorder definitions | `SetupRecordersFromRegistry = 1` |
### [Preferences]
Paths used across ADS. These correspond to `Tools > Options > Recorder Folders` and to folders the
installer seeds.
| Key | Purpose |
|---|---|
| `DataFolder` | Root folder for recorded session data. |
| `LocalFolder` | Temporary/working folder. |
| `WorkbookFolder` | Workbook folder. Also supplies the default location of the server settings file, `\AtlasServer.sbk`. |
| `ConfigFolder` | Logging configuration folder. |
| `CircuitsFolder` | Circuit files. |
| `BitmapsFolder` | Bitmap files. |
| `CustomDisplaysFolder` | Custom display definitions. |
| `FunctionLibraryFolder` | Function library. |
| `FunctionDataFolder` | Function data. |
| `FunctionDLLFolder` | Function DLLs. |
| `ExportJobFolder` | Export job definitions. |
| `DefaultConstantsFile` | Default constants file. |
| `SystemMonitor7BaseFolder` | System Monitor base folder. Multiple paths may be separated with semicolons. |
| `AncilliaryParametersFolders` | Ancillary parameter folders, semicolon-separated. Note the spelling of this key — it contains a doubled `l`. |
| `ParameterUnlockListDir` | Parameter unlock list folder. Also passed to SQL Race as its unlock list search path. |
| `CustomPGVFolder` | Folder where the LDF recorder stores received PGV files. |
| `DefaultSqlRaceConnection` | Default SQL Race connection. |
| `ATLASIniFile` | Location of this file. **Registry only** — cannot be set here. |
!!! note
`HomeFolder` is deliberately excluded — it is read from the registry only and ignores this file.
### [ADSAdvancedSettings]
This is the main section and covers every setting on the `Tools > Options` tabs. Because there are
roughly 200 of them, they are documented with their descriptions and defaults in the
**[Options reference](options.md)**, which lists the `ATLAS.ini` key for each setting alongside its label in the interface.
### [AtlasDataServer]
The network interface settings from `Setup > Configure Interfaces > General`.
!!! warning "Only read when `InitializeFromRegistry` is set"
ADS normally loads these from the server settings workbook (`.sbk`). This section is ignored
entirely unless `InitializeFromRegistry = 1`. There are also no built-in defaults here: a key you leave out is read as zero or empty, not as a sensible default. Set the whole group together.
| Key | Type | Purpose |
|---|---|---|
| `InitializeFromRegistry` | Boolean | Must be `1` for the rest of this section to be read. |
| `Stream` | String | Data server name, as seen by clients. |
| `Port` | Number | Network port. The multicast port is implicitly `Port + 1`. |
| `StatusPort` | Number | Status port. |
| `LocalIPBind` | String | IP address of the network adapter to bind to. |
| `MulticastIP` | Number | Multicast address, stored as a packed number. See below. |
| `TelemTTL` | Number | Telemetry time to live, 0–10. |
| `TelemMaxDataRate` | Number | Telemetry maximum data rate in KB/s, 0–15000. |
| `TelemBuffer` | Number | Telemetry buffer in MB, 1–1024. |
| `WireTTL` | Number | Wirelink time to live. |
| `WireMaxDataRate` | Number | Wirelink maximum data rate in KB/s. |
| `SendSessionConstantsToClients` | Boolean | Corresponds to `Use Server Constants` on the Library tab. |
`MulticastIP` is stored as a packed number rather than dotted-quad text, and the first octet must be in the range 224–239. Rather than calculating it, set it once in `Setup > Configure Interfaces` and read the stored value back — see [Capturing a configuration](#capturing-a-configuration-from-a-configured-machine).
!!! note
`WireBuffer` exists as a registry value and is written when settings are saved, but the wirelink buffer is fixed at 1 MB when read. Setting it has no effect.
### [ADSAdvancedSettings\RecorderSettings]
Recorder definitions, so that a machine comes up with its recorders already configured.
!!! warning "Only read when `SetupRecordersFromRegistry` is set"
Put `SetupRecordersFromRegistry = 1` in `[ADSAdvancedSettings]` first, otherwise recorders are
loaded from the workbook and this section is ignored.
With this enabled, ADS also *saves* recorders back to the registry when settings are saved. Any recorder in `ATLAS.ini` is re-applied on the next start, so recorders added through the interface will appear to be lost.
| Key | Purpose |
|---|---|
| `RecorderCount` | Number of recorders to create. |
| `RecorderType` | Recorder type, `N` starting at 1. Must exactly match one of the strings below. |
| `Recorder__NumberOfSettings` | Number of sources this recorder has. See the warning below. |
| `Recorder__0_` | Per-recorder properties, for example `Recorder_1_0_SessionDirectory`. |
Commonly used properties include `AutoRecord`, `SessionDirectory`, `SessionName`,
`SessionDestination`, `DataStream`, `DataSource`, `AppendSession`, `RecordOnlyToMemory`,
`DetailsComeFrom`, `CarName`, `UnitName`, `SqlRaceConnectionIdentifier`,
`RemoteDataServerIPAddress` and `RemoteDataServerPort`.
`SessionName` supports the same substitutions as the Record dialog, such as `%y%m%d%H%M%S` for a
timestamp or `$vCar$` for a parameter value.
!!! warning "`NumberOfSettings` must match the recorder"
`Recorder__NumberOfSettings` must equal the number of sources the recorder type actually has — `1` for a single-source recorder. If it does not match, the **entire** `Recorder__0_*` block is silently ignored and the recorder is created with default settings. Session detail blobs are also stored in binary form and cannot be expressed in the file, so drive naming through `SessionName`, `SessionDirectory` and `DetailsComeFrom` instead.
If in doubt, configure one recorder in the interface and read the values back, as described
below.
#### Valid recorder type strings
`RecorderType` is matched against the recorder types registered by ADS, exactly and including
spaces and capitalisation. Several are only registered if the corresponding licence option is
present; if the string does not match, the recorder is skipped and `Recorder Type: , not found` is written to the log.
| `RecorderType` | Licence option required |
|---|---|
| `File Telemetry` | — |
| `Generic Recorder` | — |
| `Remote Data Server` | — |
| `Remote Data Server Playback` | — |
| `Ethernet Multi-Session Offload` | — |
| `Data Server Telemetry` | — |
| `VTSRecorder` | vTAG Server Recorder |
| `DST Multi Source Recorder` | Wide Band |
| `Generic SQLRace Recorder` | SQLRace read |
| `Advanced Data Feed Recorder` | Advanced Data Feed Recorder |
| `TLM-Px Multi Source Recorder` | TLM-Px Recorder |
!!! note
`CBR610 Multi Source Recorder` and `PiDB Multi Source Recorder` are valid strings elsewhere in
ATLAS but are **not** registered as ADS recorder types.
## Worked examples
### Enable the Bridge Service
The minimum file to turn on the Bridge Service and have ADS manage the process itself:
```ini
; \McLaren Electronic Systems\ATLAS 9\Atlas.ini
[ADSAdvancedSettings]
EnableRemoteDataFeed = 1
LocalRemoteDataFeed = 1
RemoteDataFeedEndpoint = [::1]:9697
```
To connect to a Bridge Service running on another machine instead, point the endpoint at it and let that machine own the process:
```ini
[ADSAdvancedSettings]
EnableRemoteDataFeed = 1
LocalRemoteDataFeed = 0
RemoteDataFeedEndpoint = bridge-host.example.com:9697
```
### Relocate data and log folders
Moving recording and diagnostic output onto a dedicated data volume:
```ini
[Preferences]
DataFolder = D:\ATLASData
WorkbookFolder = D:\ATLASData\Workbooks
ConfigFolder = D:\ATLASData\Config
[ADSAdvancedSettings]
LogFileFolder = E:\ATLASLogs
SettingsFile = D:\ATLASData\Workbooks\AtlasServer.sbk
MinimumDiskSpace = 2000
TempRecordingDirectory = D:\ATLASData\Temp
MaxLogFileSizeMB = 50
```
### A complete unattended configuration
Network interfaces, one auto-starting recorder and the Bridge Service, all applied on first start:
```ini
; ADS configuration - applied at start-up, read-only in Tools > Options.
; Restart ADS after editing. Save as ANSI, not UTF-16.
[Preferences]
DataFolder = D:\ATLASData
WorkbookFolder = D:\ATLASData\Workbooks
[ADSAdvancedSettings]
; --- diagnostics ---
LogFileFolder = E:\ATLASLogs
MaxLogFileSizeMB = 50
; --- Bridge Service ---
EnableRemoteDataFeed = 1
LocalRemoteDataFeed = 1
RemoteDataFeedEndpoint = [::1]:9697
; --- gates for the two sections below ---
SetupRecordersFromRegistry = 1
[AtlasDataServer]
InitializeFromRegistry = 1
Stream = TrackADS1
Port = 5000
StatusPort = 5002
LocalIPBind = 10.20.0.5
MulticastIP = 4009754848
TelemTTL = 1
TelemMaxDataRate = 500
TelemBuffer = 20
WireTTL = 1
WireMaxDataRate = 500
[ADSAdvancedSettings\RecorderSettings]
RecorderCount = 1
Recorder1Type = Data Server Telemetry
Recorder_1_NumberOfSettings = 1
Recorder_1_0_AutoRecord = 1
Recorder_1_0_SessionDirectory = D:\ATLASData\Telemetry
Recorder_1_0_SessionName = %y%m%d%H%M%S
Recorder_1_0_SessionDestination = 0
Recorder_1_0_DetailsComeFrom = 0
```
!!! tip
Take the `MulticastIP` value from a machine you have already configured rather than computing it. The value above is an example and will not be correct for your network.
## Capturing a configuration from a configured machine
The most reliable way to build an `ATLAS.ini` — particularly for recorders and `MulticastIP` — is to configure one machine through the interface, then read the values back and transcribe them.
Configure ADS as required, close it so that settings are flushed, then export:
```powershell
reg export "HKCU\Software\McLaren Electronic Systems\ATLAS\9.0\ADSAdvancedSettings" ads-settings.reg
```
Or list a section's values to read them directly:
```powershell
reg query "HKCU\Software\McLaren Electronic Systems\ATLAS\9.0\AtlasDataServer"
```
Each value name becomes a key in the matching `ATLAS.ini` section, and each sub-key becomes a section with a backslash in its name. Remember that multi-string and binary values cannot be transcribed.
## Checking that your file was read
ADS logs whether it found the file each time it starts. Look in `ATLASWideLog.txt` in the folder
given by `LogFileFolder`:
```
ATLAS ini file found; C:\Users\jsmith\Documents\McLaren Electronic Systems\ATLAS 9\Atlas.ini
```
If the file was not located, the same line reports `ATLAS ini file is not found` with the path that was tried — which tells you where ADS expected it.
Then confirm individual settings: open `Tools > Options` and check that the settings you supplied are greyed out. A setting that is still editable did not come from the file.
## Troubleshooting
| Symptom | Likely cause |
|---|---|
| Nothing changed at all | ADS was not restarted, or the file is in a different account's Documents folder. Check the log line above. |
| Log says the file was not found | Wrong path, wrong file name, or Documents is redirected. The logged path is the one ADS tried. |
| A boolean behaves as if disabled | Written as `true`/`false` instead of `1`/`0`. |
| A setting is still editable in Options | The section or key name does not match, or the value was rejected. Section names are the registry sub-key, key names the registry value name. |
| A whole section is ignored | Missing gate: `InitializeFromRegistry` for `[AtlasDataServer]`, `SetupRecordersFromRegistry` for recorders. |
| A section appears partly applied | The section header is duplicated in the file; only the first block is read. |
| A recorder was not created | `RecorderType` does not exactly match a registered type, or its licence option is absent. The log records `Recorder Type: , not found`. |
| A recorder has default settings | `Recorder__NumberOfSettings` does not match the recorder's source count, so the property block was skipped. |
| Values look garbled | The file was saved as UTF-16. Save as ANSI. |
| Bridge Service uses the wrong endpoint | `ATLAS.ini` was relocated with `ATLASIniFile`. Set `RemoteDataFeedEndpoint` in the registry, or move the file back to the default path. |
## Setting values in the registry instead
Every key described here is a registry value under
`HKEY_CURRENT_USER\Software\McLaren Electronic Systems\ATLAS\9.0`, so a deployment script can write the registry directly:
```powershell
$key = 'HKCU:\Software\McLaren Electronic Systems\ATLAS\9.0\ADSAdvancedSettings'
New-Item -Path $key -Force | Out-Null
Set-ItemProperty -Path $key -Name 'EnableRemoteDataFeed' -Value 1 -Type DWord
Set-ItemProperty -Path $key -Name 'LocalRemoteDataFeed' -Value 1 -Type DWord
Set-ItemProperty -Path $key -Name 'RemoteDataFeedEndpoint' -Value '[::1]:9697' -Type String
```
Use booleans and numbers as `DWord` and text as `String`.
Choose between the two approaches on this basis:
| | `ATLAS.ini` | Registry |
|---|---|---|
| Settings remain editable in the interface | No — greyed out | Yes |
| Multi-string and binary values | Not supported | Supported |
| Applies per user | Yes, via that user's Documents folder | Yes, via that user's hive |
| Easy to copy between machines | Yes, one file | Requires a `.reg` export or script |
Because it locks values and travels as a single file, `ATLAS.ini` is the better fit for deployment. Use the registry for the few things the file cannot express, and where operators still need to be able to change a setting.
!!! note "The installer does not configure ADS"
The ADS installer cannot apply configuration. It is a bootstrapper that installs prerequisites
and then the ADS package, and it declares no variables that would let it pass settings through — so only the standard silent-install switches (`/quiet`, `/passive`, `/log`) apply, and none of them configure ADS.
Treat configuration as a separate step: install ADS, then write `ATLAS.ini` or the registry
values, then start ADS.
## See also
- [Options reference](options.md) — every ADS setting with its `ATLAS.ini` key, default and description
- [Getting Started](installation.md) — installing and first-run setup
- [Recorders](recorders.md) — what each recorder type does
- [RDS](rds.md) — Remote Data Server configuration
---
# RDS
The Remote Data Server enables listening to another ADS server across different networks over WAN connections. This functionality is essential for distributed teams, allowing factory floor personnel to access real-time data being transmitted from remote locations.
## Configuring Remote Data Server
1. On the ADS machine, go to `Tools > Options > Recording`
2. Find `Enable Remote Data Server` and set it to `True`

3. Go to the `Slave ADS Connection 1` tab and Allow Connection.
4. Click `OK` to save and close the Options window.
5. On the RDS machine, go to `Setup > Add > Remote Data Server` Recorder.
6. Configure the recorder by entering the IP address and port of the ADS machine (as defined in Slave ADS Connection settings).

7. Turn Auto-Record on if you want the Remote Data Server to receive telemetry automatically when the main ADS starts a session.
8. Click `OK` to save the recorder settings.
!!! info "RDS Playback"
When you enable **Sync RDS Playback File**, the system creates a playback file to recover lower-priority packets that were deprioritized during the session. This playback file can be upserted to the main session using the RDS Playback Recorder.
## Remote Data Server (RDS) Options
| Setting | Description |
|---------|-------------|
| **Allow connection** | Select to allow a Slave ADS to connect to the local ADS |
| **Port** | Port to be used by a Slave ADS |
| **Auto data rate** | Automatically adjusts data rate for optimum bandwidth usage |
| **Max data rate** | Maximum data rate in Kb/s (0 = unlimited) |
| **Min data rate** | Minimum data rate when Auto data rate is disabled |
| **Compression** | Select to apply data compression |
| **Data distribution** | Eliminates data banding by evenly distributing received packets |
## Data Server Telemetry Recorder
The Data Server Telemetry Recorder daisy-chains multiple data servers together by mirroring the primary Data Server stream to downstream clients.
!!! tip "Networking Considerations"
- **Same Network:** Can be used when all Data Servers reside on the same network
- **Different Networks:** Must use Remote Data Server recorders instead of DST recorders for cross-network deployment
Remote Data Server lets you listen to another ADS server on a different network over WAN. This is used by teams so that people in the factory have access to the data currently being transmitted.
---
# Overview
A standard, open set of rules and services for streaming telemetry data over a broker. Includes full definition of
the Protobuf schema for transmitting messages, along with documentation describing the
messages.
!!! tip "New to Open Streaming?"
See the [Getting Started Guide](../../../developer-resources/secu4/getting-started.md) to get data flowing in 30 minutes using the Docker-based quick start, or explore the [example repository](https://github.com/atlas-dev-hub/example-stream-api-kafka-setup) for a hands-on walkthrough.


## Components
### [Stream API](../../../developer-resources/secu4/stream_api/index.md)
A standard API to expose streaming data from SECU units and abstract away proprietary
implementation details. Consumers of this API will be able to write software that
interfaces with any viewer, network protocol, or storage technology of their choice.
All the data from the SECU unit (after RDA filtering) will be available on the stream.
This will be integrated with a protocol for streaming engineering (calibrated)
telemetry, interoperating with ATLAS clients and the surrounding data processing
ecosystem.
### [Bridge Service](../../../developer-resources/secu4/bridge_service/index.md)
Standalone service that decodes a raw stream of quads from an ADS, converting the data
to engineering values then into the Stream Protocol via the Stream API. Will include
components to manage sessions, configuration, metadata etc. All RDA protected data will
be filtered out at this point, based on the active team license, so any downstream
components will only receive data available to the team.
### Virtual Parameter Service
Virtual parameters are defined as simple FDL functions in the ECU logging config, and
are traditionally calculated on demand by clients rather than the values being persisted
like other parameters. However, this requires knowledge of the proprietary FDL grammar,
so a service will be developed as part of the Motion Applied Bridge Service to
calculate virtual parameters in real time and written to the broker, eliminating the
need for downstream clients to recalculate them.
### Multicaster Service
An optional service to reduce network bandwidth in situations where a large number of
clients are reading the same set of data from the same broker. Can be configured to
consume specific streams of data from the broker, and forward all the packets over
multicast to listening clients.
## Historical Data Storage (Parquet)
In addition to the ATLAS session formats, a Parquet format will be supported for storing
open engineering data directly from the stream or as an export from ATLAS.
Parquet is an open-source file format for storing large datasets in an optimized way.
Columnar storage allows for fast data processing and good compression rates. Parquet
files can be easily accessed using a variety of programming languages and APIs, to allow
teams to access their data independent of ATLAS.
---
# Overview
Tooling to add upon existing raw data to augment and enrich for more advanced simulation
## [vTAG Server](vtag/index.md)
vTAG Server is a computation engine that runs Simulink‑based logic on live or historical telemetry to generate new derived data without relying on physical hardware.
### Key Functionality
- Live & historical data processing: Replays telemetry streams or session files and executes Simulink‑compiled algorithms on them to produce new computed channels.
- External computation offload: Shifts non‑critical or CPU‑heavy logic away from on‑car ECUs, reducing hardware load and enabling safer experimentation.
- Data publishing into ATLAS: Outputs vData back into the ATLAS ecosystem so processed signals appear as native channels for analysis, distribution, and recording.
---
# Overview
vTAG Server is part of the ATLAS ecosystem and provides a way to run Simulink‑based logic on real data—either live telemetry or historical sessions—without requiring a physical ECU or embedded unit. The aim is to offload computationally expensive or non‑critical logic from hardware and to provide a safe, flexible environment for algorithm development.
Many engineering teams reach a point where:
- The physical unit’s CPU is at capacity.
- Telemetry bandwidth limits how much data can be streamed.
- Testing on real hardware introduces delays or risks.
- They need to interrogate or transform existing session data without modifying the original datasets.
vTAG Server solves these problems by acting as an external computation engine: it replays data, executes your Simulink logic on it, and publishes new derived parameters. This allows engineers to test ideas, optimise algorithms, or shift load off embedded devices.
## Key Features
- **Data Integration**: The complete data stream is displayed in ATLAS as if all data came from the car
- **Network Distribution**: One ATLAS Client typically runs the vTAGServer and supplies processed data (vData) to the VTS Data Recorder in the ADS, which distributes it across the network
- **Session Processing**: In stand-alone historical use, vTAGServer processes data from a session (.ssn) file and creates vTAG data in another vTAG session (.ssv) file
!!! note "What's the difference between vTAG Server and vTAG PC?"
Although vTAG Server and vTAG PC use the same build mechanism, they serve different engineering goals:
vTAG Server:
- Processes real data (historical or live).
- Acts as an external computation engine.
- Suitable for validation of logic on production telemetry.
- Publishes outputs into the ATLAS ecosystem.
vTAG PC:
- A software‑in‑the‑loop emulator.
- Runs like an ECU but entirely on your computer.
- Optimised for debugging and functional testing of embedded code, not replaying data.
Engineers typically use vTAG PC to test behaviour, and vTAG Server to test behaviour against real data.
---
# Getting Started
This guide provides the fastest, simplest path to building and running your first vTAG Server application — from a blank Simulink model to live outputs in ATLAS.
## 1. Install & Verify Required Components
Before you begin, ensure you have the following:
**Software**
- MATLAB + Simulink
- System Monitor
- ATLAS
- ADS (Atlas Data Server)
**Licenses**
- MCT licence (needed for Measurement Write blocks)
- MCT Atlas Toolbox licence (required for Atlas 10 Source block)
- MCT vTAG HSP licence (required to build vTAG applications)
!!! note
To learn more about licences, please contact [sales](mailto:sales@motionapplied.com).
**Download**
Download the latest vTAG Server installation package from [Motion Applied Portal](https://portal.mclarenapplied.com/portal/Downloads/Software#vTAG%20Server).
## 2. Create Your First vTAG Server Model
1. Open Simulink → select **New model**.
2. In the Library Browser, find `MCT ATLAS Toolbox > ATLAS10`.
3. Add an **Atlas 10 Source block**:
- Pick a parameter (e.g., `vehicle_speed`)
- Select the correct originating application
- You can define sample times, modes, data types, etc. as needed by clicking into the block.
4. Add simple logic — for example, a **Gain block** multiplying by 2.
5. Add a **Measurement Write block**:
- Name the output parameter (e.g., `vehicle_speed_x2`)
6. Save the model.
You now have the simplest valid vTAG model:
```
Input → Logic → Output
```
!!! question "What are the blocks in MCT ATLAS Toolbox?"
- ATLAS 10 Source – Reads a parameter from a live ADS data stream or a historical session file and provides it as an input to your Simulink model.
- ATLAS 10 Source Type – Outputs a status code indicating whether the connected data source is live, historical, or unavailable to support diagnostics or logic switching.
- ATLAS 10 Control – Allows you to run a Simulink simulation driven by ATLAS while a session is loaded, effectively acting as a local replacement for vTAG Server during testing. *Not required for vTAG Server.*
- ATLAS 10 Sink – Sends Simulink‑generated signals back into ATLAS during simulation so they appear as channels in the viewer.*Not required for vTAG Server.*
## 3. Build the Application (pgv)
Before building, configure the model:
1. Open **Model Settings** → **Code Generation**.
2. On **System Target File** Select **vTAG TLC**.
3. Under **Build Process > Toolchain** Choose your Microsoft Visual C compiler.
4. Click **Ok**.
Run the build command in MATLAB to create the PGV file:
```matlab
vtag.build( ...
'modelName', 'your_model_name', ...
'Application', 9,
'PGVVersion', 'MyFirstVtagApp', ...
'SMBase', 'path/to/SystemMonitor/base' ...
);
```
For more information on the build command and its arguments type `help vtag.build` in MATLAB Command Window.
After running the build command, go to the SMBase folder and find the folder generated with PGVVersion (e.g., `MyFirstVtagApp`). Inside, you will find the generated `.pgv`, `.dtv` and `.dvb` files. To learn more about projects, see [System Monitor](../../configure/system-monitor/projects/index.md) documentation.
## 4. Reprogram the vECU
Now that we have the PGV file, we need to reprogram it onto the virtual unit.
1. Open **System Monitor**.
2. Create a **New Project** (`File > New > Project).
3. Select BIOS Program Version
- If vtag.build didn't specify a BIOS version, the default is 4; select a 1000 BIOS Version.
4. Select all of the App IDs in the selected base and load the generated PGVs.
5. Click **Finish**
6. Connect to the **vTAG Server IP**.
- The vTAG Server IP can be found in vTAG Server under `Own IP`.
7. In vTAG Server, click **Reset > Reset vECU**.
8. Reprogram the unit (F3).
## 5. Configure ADS
Configure ADS:
1. Open **ADS**.
2. Add a **File Telemetry Recorder** (simulated data source).
3. Add a **VTS Recorder** (records vTAG Server output).
4. Start **ADS recording**.

Check that **vTAG Server** shows active in System Monitor.
## 6. View in ATLAS Viewer
1. Open ATLAS Viewer and a workbook.
2. Open Session Browser (`Ctrl + L`) and add a new [Data Server Telemetry Recorder](../../analyse/viewer/handling-data/recorders/data-server.md), enable auto-record and add to set.
3. View your live output parameter streaming in.
This setup lets you simulate a live telemetry environment without hardware.
---
# Operating vTAG Server
vTAG Server contains 6 tabs plus a bottom control section showing Process State and Progress. All vTAG Server settings are saved within the workbook.
vTAG Server has the following tabs:
- **Settings** – configure vTAGServer
- **Status** – view processing and recording information
- **Reset** – vECU control
- **APP Info** – view information on APPs
- **Log** – view logging output
- **Control section** – operate the model and view progress

## Settings Tab
### Live Mode
In Live Mode you can:
- Set the IP address
- Check/uncheck parameter options
- Stop the model
### Historical Mode
In Historical Mode you can:
- Set .ssv file name
- Set calculation period
- Play and stop the model
### General Workflow
1. Choose Live or Historical from the Mode list.
2. Choose your own IP address (the machine running ATLAS).
3. In Historical Mode, specify a session name (part used by extension manager). If omitted, the .ssv file name matches the .ssn file.
4. Define the Calculation Period:
- Session
- Current Lap
- Fastest Lap
- All Timed Laps
- Current Time Base
5. Wait for parameters up to X seconds.
6. Re‑run model on cable data – when enabled, VTS recorder records during ATLAS wire‑link upload and generates a new .ssv file.
7. Use coverage cursor (Live only) – recommended. Ensures Apps run on complete data.
8. Channel latency (up to 4s) is considered.
9. Auto reload historical run – automatically loads .ssv after generation.
10. Delay – apply constant delay without using coverage cursor.
## Status Tab
Displays:
- Logging Status
- Memory Size (MB)
- Memory Used (MB)
- Parameter List – parameters created by vTAGServer
### Possible Logging States
- Cleared
- Cleared to Logging
- Stopped
- Logger Only
- Telemetry Only
- End of Logging Pending
- Download Request
- Download Pending
- Download
- Full Reset Request
- Erase
- Disabled
- Reconfiguration Request
- Reconfiguration
## Reset Tab
- **Reset virtual ECU** – reinitialises applications, BIOS, and logging memory.
- **Clear vECU** – removes PGVs and logging configuration. Use whenever programming a new PGV via System Monitor.
## APP Info Tab
Shows:
- Models running per APP
- BIOS usage
- Parameters and PGVs used
## Log Tab
Displays the log, also saved as a standard log file.
### Options:
- **Autoscroll** – disable to stop auto‑scroll
- **Filter out trace** – filters debug information
## Control Section
### Live Mode
- Start/Stop the model
### Historical Mode
- Play/Stop the model
- Progress bar shows processing progress
- Progress may pause temporarily while searching for PGVs
### Process States
- Stop
- Stopped on Error
- Running Live
- Running after Upload
- Running Historical
!!! tip
- The Process States and the progress are shown in the 'control' part.
- When running live, no progress is shown. When running on Wire Link Upload or Historical, you can see the progress.
- Note that in Historical mode the progress bar sometimes 'holds' for a few seconds. vTAGServer is then searching for the PGV's (this will be shown in the Status Bar of ATLAS Viewer)
---
# Live & Historical Usage
vTAG Server can operate in two ways depending on the data source:
- **Live Mode** – processes parameters from an active ADS telemetry stream.
- **Historical Replay Mode** – replays a previously recorded session file (SSN or SQL Race).
The behaviour of your vTAG model is the same in both modes: it reads parameters via Atlas 10 Source blocks, executes the Simulink logic, and publishes outputs via Measurement Write.
## Live Usage (ADS Telemetry)
When a live telemetry stream is active in ADS, the vTAG Server instance connected via VTS Recorder will begin producing output parameters in real time.
### What you will see
- ATLAS will display live parameters from the telemetry stream.
- Additional derived parameters from your vTAG Server model appear alongside them.
- If ADS is configured with Auto‑Record, both the actual telemetry and the VTS Recorder output are recorded continuously.
!!! note
- vTAG Server processes samples as they arrive.
- If live telemetry contains coverage gaps (network dropouts), vTAG Server cannot backfill the missing samples later.
- The output during live operation will therefore include any gaps present in the incoming signal.
## Wire‑Link Upload (End‑of‑Session Offload)
When telemetry coverage is imperfect, some data is only available after the wire‑link offload at the end of a run.
After offload, once the complete session is available:
- The system can automatically switch to Historical Replay Mode.
- vTAG Server can replay the session from start to finish using the full, gap‑free dataset.
- It regenerates the entire set of derived parameters using the higher‑quality data.
This ensures that the simulated parameters are based on the complete dataset, not just what was available live.
If ATLAS detects that additional data has arrived after live recording:
- The vTAG model may be re-run over the full session with the improved dataset.
- The newly generated outputs are written to the same directory as the original VTS data.
- The version number (iteration counter) increments automatically to distinguish reprocessed files.
## Stand‑Alone Historical Usage (Full Session Replay)
If you have access to a complete SSN or SQL Race session, you can perform a stand‑alone vTAG replay directly inside ATLAS.
To run a historical replay:
1. Open ATLAS.
2. Load the session you want to analyse.
3. Select the vTAG Server layer as the data source.
4. Choose the correct vTAG Server instance (IP address under Options → Choose).
5. Define the time span if required (Current Lap, Fastest Lap, Entire Session, etc.).
6. Start playback — ATLAS will display the derived parameters from vTAG Server.
This allows you to run diagnostic or engineering models using complete, offline session data without ADS or live telemetry.
## Session File Naming (VTS Recorder)
The VTS Recorder generates output session files containing the vTAG‑derived parameters. If the active recorder outputs a base session name `xxx.ssn`, the VTS Recorder produces:
```
xxx.VTS.001.ssv
xxx.VTS.002.ssv
xxx.VTS.003.ssv
...
```
Where:
- `xxx` = base session name (taken from the active recorder or the name entered in VTS Recorder).
- `VTS` = the identifier for the vTAG source (configurable).
- `nnn` = iteration number (starting at 001).
Each time the vTAG Server performs a fresh playback (live or historical), the version number increments.
When running a replay without ADS you can enter the base session name manually. Each new playback produces a new version automatically.
## Opening Multiple Sessions in ATLAS
ATLAS can display actual data and vTAG‑generated data together.
### How ATLAS handles simulated session versions
- ATLAS shows one column for each unique vTAG identifier (the VTS part of the filename).
- It automatically finds all versions of simulated output files created for the same base session.
- The highest version is selected by default.
- Users can switch to earlier iterations if needed.
This allows easy comparison of re‑processed sessions (e.g., live vs. offloaded vs. "clean" full replay).
!!! note "Session Persistence"
- vTAG Server does not remember state between sessions.
- If you need multi‑session continuity (e.g., cumulative metrics), you must:
- Create a synthetic "start block" (short session containing required initial values).
- Stitch sessions together using SQL Race APIs.
This is necessary because vTAG Server always starts a replay from zero state.
---
# Overview
The **Virtual Parameter Service (VPS)** simplifies the calculation of virtual parameters — parameters defined as FDL (Function Definition Language) functions in ECU logging configurations. Traditionally calculated on demand by downstream clients such as ATLAS, the VPS performs these calculations **in real time** and writes the results back to the broker, removing the need for client-side recalculation.
## Key Features
| Feature | Description |
|---|---|
| **Real-time virtual parameter calculation** | Automatically computes FDL-defined virtual parameters as live telemetry data arrives. |
| **Stream API integration** | Reads source sessions from Kafka and writes computed results back as new virtual sessions. |
| **Session lifecycle management** | Detects live sessions, creates associated virtual sessions, and manages their full lifecycle. |
| **Prometheus metrics** | Exposes detailed operational metrics for monitoring via Prometheus and Grafana. |
| **Docker-first deployment** | Ships as a public Docker image, alongside a Windows binary for running outside Docker. |
| **Configurable buffering** | Tunable buffering window and sliding window percentage to balance latency and throughput. |
## How It Works
At a high level, the VPS operates as a background service that:
1. **Connects** to a Kafka broker via the Stream API.
2. **Listens** for live telemetry sessions published by ADS through the Bridge Service.
3. **Reads** configuration packets containing parameter definitions and FDL expressions.
4. **Compiles** FDL expressions into executable functions at runtime.
5. **Subscribes** to source parameter data streams and buffers incoming samples.
6. **Calculates** virtual parameter values in real time using the compiled functions.
7. **Writes** the computed results back to the Stream API as an associate session.
Downstream clients can then consume these pre-calculated virtual parameters directly from the stream, instead of computing them locally.
```mermaid
flowchart LR
ADS["ADS (ATLAS)"] -->|Telemetry| BS["Bridge Service"]
BS -->|Publishes to| K["Kafka"]
K -->|Sessions & Data| VPS["Virtual Parameter Service"]
VPS -->|Computed Virtuals| K
K -->|Virtual Data| C["ATLAS Viewer"]
```
## Use Cases
- **Eliminating redundant calculations** — Instead of every client independently computing the same virtual parameters, the VPS computes them once and publishes the results.
- **Ensuring consistency** — All consumers receive identical computed values, removing discrepancies between different client implementations.
- **Reducing client load** — Downstream applications no longer need to include FDL evaluation logic, simplifying their architecture.
---
# Getting Started
This guide walks through deploying the Virtual Parameter Service using Docker (recommended) or running it manually.
## Prerequisites
Before deploying the Virtual Parameter Service, ensure the following dependencies are in place.
### Required Software
| Software | Minimum Version | Purpose |
|---|---|---|
| **ADS (ATLAS Data Server)**, running the [Bridge Service](../../../developer-resources/secu4/bridge_service/index.md) | `9.85.2.183` | The VPS's actual data source — Bridge Service publishes live telemetry to Kafka; ADS is what runs it |
| **Docker** | Latest stable | Container runtime for deploying the service stack |
| **Kafka** | Latest (via Confluent images) | Message broker for the Stream API |
### Bridge Service
The VPS doesn't talk to ADS directly — it consumes live telemetry from Kafka topics published by the **Bridge Service**, which runs alongside ADS. Set up and enable Bridge Service following its own [configuration guide](../../../developer-resources/secu4/bridge_service/index.md); several of its settings need to line up with the VPS's own configuration, or the VPS will be listening in the wrong place:
- **`DataSource`** — the VPS's `DataSource` setting (see [AppConfig Reference](configuration/appconfig-reference.md)) must match the DataSource name Bridge Service publishes under.
- **`BrokerUrl`** — the VPS's `StreamApiConfig.BrokerUrl` must point to the same Kafka broker Bridge Service is configured to publish to.
- **`StreamCreationStrategy`** — the VPS's `StreamApiConfig.StreamCreationStrategy` must match Bridge Service's (`1` = partition-based, `2` = topic-based), since it determines where in Kafka the data actually lands.
- **`PartitionMappings`** — only relevant when `StreamCreationStrategy` is `1` (partition-based); the VPS's `StreamApiConfig.PartitionMappings` must match Bridge Service's mapping so the VPS reads from the same partitions Bridge Service writes to. Not used for topic-based (`2`).
### Docker Access
The VPS Docker image is public, hosted on Docker Hub as [`atlasplatformdocker/virtual-parameter-service-host`](https://hub.docker.com/repository/docker/atlasplatformdocker/virtual-parameter-service-host/general). No special access is required — `docker login` is only needed to avoid Docker Hub's anonymous pull rate limits.
!!! note "Can't reach Docker Hub?"
If your environment can't pull from Docker Hub at all (e.g. an offline/air-gapped machine), see [Offline Install](setup-guide.md#offline-install) below.
### Network Requirements
| Port | Service | Description |
|---|---|---|
| `9094` | Kafka | Broker listener for external clients |
| `10010` | VPS Metrics | Prometheus metrics endpoint |
| `13579` | Stream API | Default Stream API port (configurable) |
!!! tip
All ports are configurable. The above are the conventional defaults if you set up this stack yourself, matching the `AppConfig.json`/image defaults documented elsewhere on this page.
## Docker Deployment (Recommended)
1. **Create a working directory** (e.g. `C:\dev\vps`) and an `AppConfig.json` inside it. See the [AppConfig Reference](configuration/appconfig-reference.md) for the full schema — at minimum, set:
- `DataSource` to match the DataSource name Bridge Service publishes under.
- `StreamApiConfig.BrokerUrl` to point to the Kafka broker Bridge Service publishes to (e.g. `YOUR_MACHINE_IP:9094` — use your machine's IPv4 address, not `localhost`, if Kafka runs in Docker).
2. **Pull and run the image**:
```bash
docker run -d \
--name virtual-parameter-service \
-p 10010:10010 \
-v C:\dev\vps\AppConfig.json:/config/AppConfig.json \
atlasplatformdocker/virtual-parameter-service-host:latest \
-c /config/AppConfig.json
```
See [Docker Run Command Explained](#docker-run-command-explained) below for what each flag does, or [Docker Compose Environment Variables](#docker-compose-environment-variables) if you're running it from your own `docker-compose.yaml` alongside Kafka and Bridge Service.
3. **Verify** — check the container is running:
```bash
docker ps
```
### Offline Install
If your environment can't reach Docker Hub at all (e.g. an offline/air-gapped machine), export the image on a machine that can reach Docker Hub, then transfer and load it on the offline machine:
```bash
# on a machine with Docker Hub access
docker pull atlasplatformdocker/virtual-parameter-service-host:latest
docker save atlasplatformdocker/virtual-parameter-service-host:latest -o vps-image.tar
# transfer vps-image.tar to the offline machine, then:
docker load --input vps-image.tar
```
Then run the container as in step 2 above.
### Docker Run Command Explained
```bash
docker run -d \
--name virtual-parameter-service \
-p 10010:10010 \
-v C:\AppConfig.json:/config/AppConfig.json \
atlasplatformdocker/virtual-parameter-service-host:latest \
-c /config/AppConfig.json \
-l /logs/vps-svc-log.txt
```
| Flag | Purpose |
|---|---|
| `-d` | Run in detached (background) mode |
| `--name` | Assign a container name for easier management |
| `-p 10010:10010` | Expose the Prometheus metrics port |
| `-v ...:/config/AppConfig.json` | Mount your local config file into the container |
| `-c /config/AppConfig.json` | Tell the service where to find its configuration |
| `-l /logs/vps-svc-log.txt` | Specify the log file path inside the container |
### Docker Compose Environment Variables
Instead of command-line arguments, you can use environment variables in `docker-compose.yaml`:
```yaml
virtual-parameter-service:
image: atlasplatformdocker/virtual-parameter-service-host:latest
ports:
- "10010:10010"
volumes:
- ./virtual-parameter-service/AppConfig.json:/config/AppConfig.json
environment:
- CONFIG_FILE_PATH=/config/AppConfig.json
- LOG_FILE_PATH=/logs/vps-svc-log.txt
```
See the [Environment Variables](configuration/environment-variables.md) reference for all supported variables.
## Manual Deployment
For running the service outside of Docker:
1. **Build or download** the `MA.DataPlatforms.VirtualParameterService.Host` binaries.
2. **Place `AppConfig.json`** in a `Configs` folder alongside the executable:
```
MA.DataPlatforms.VirtualParameterService.Host.exe
Configs/
└── AppConfig.json
```
Or specify a custom path at startup with `-c`:
```bash
MA.DataPlatforms.VirtualParameterService.Host.exe -c C:\path\to\AppConfig.json
```
3. **Run the executable**:
```bash
MA.DataPlatforms.VirtualParameterService.Host.exe
```
!!! warning "Administrator privileges required"
The Prometheus HTTP listener requires the application to run with elevated (Administrator) privileges.
4. **Optional: specify the log file path**:
```bash
MA.DataPlatforms.VirtualParameterService.Host.exe -c C:\config\AppConfig.json -l C:\logs\vps.txt
```
If no log path is specified, logs are written to:
```
%ProgramData%\Mclaren_Applied_Ltd\VirtualParameterService\Logs\vps-svc-log.txt
```
## Verifying the Deployment
Once the service is running:
1. **Check the metrics endpoint** — Navigate to `http://YOUR_MACHINE_IP:10010/metrics` in a browser. You should see Prometheus-formatted metrics.
3. **Look for the data source gauge** — Search for `vps_running_gauge_of_data_sources` in the metrics output. Its value should match the number of data sources you configured.
4. **Optional: Prometheus and Grafana** — if you've set up your own Prometheus/Grafana instances against the VPS metrics endpoint, confirm the VPS target shows `UP` in Prometheus and query the metrics from Grafana. See the [Metrics & Prometheus](monitoring/metrics.md) and [Grafana Dashboards](monitoring/grafana.md) guides.
---
# AppConfig Reference
The VPS is configured via a single JSON file — `AppConfig.json`. This page documents every section and setting.
## File Location
By default, the service looks for the config file at:
```
Configs/AppConfig.json
```
This path is relative to the executable or working directory. Override it using:
- **Command-line argument:** `-c /path/to/AppConfig.json`
- **Environment variable:** `CONFIG_FILE_PATH=/path/to/AppConfig.json`
## Full Example
```json
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "192.168.0.6:9094",
"PartitionMappings": [{}],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"BatchingResponses": false,
"StreamApiPort": 13579
},
"VirtualParameterServiceConfig": {
"DataSource": "Default",
"BufferingWindowLengthInMs": "3000",
"SlidingWindowPercentage": 5,
"SessionTypesToProcess": [ "Session", "VTS" ],
"MetricPort": 10010,
"CalculationMode": "Default",
"MaxWriteBatchSizeInKb": 100
},
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "C:/logs/vps-svc-log.txt"
}
}
]
}
}
```
## VirtualParameterServiceConfig
Controls the core behaviour of the virtual parameter calculation engine.
| Setting | Type | Default | Description |
|---|---|---|---|
| `DataSource` | `string` | `"Default"` | The data source name to listen for. Only **one** data source is supported per service instance. Must match the data source configured in ADS. |
| `BufferingWindowLengthInMs` | `uint` | `3000` | The time window (in milliseconds) over which incoming sample data is buffered before processing begins. Increasing this value allows more data to accumulate before calculation, which can improve accuracy at the cost of latency. |
| `SlidingWindowPercentage` | `byte` | `5` | The percentage of the buffering window that controls how frequently computed data is emitted. For example, with a 3000 ms window and 5%, results are emitted approximately every 150 ms. |
| `SessionTypesToProcess` | `string[]` | `["Session", "VTS"]` | The ATLAS session types the service processes. Historical sessions and the service's own virtual-session output are filtered out automatically regardless of this setting. |
| `MetricPort` | `int` | `10010` | The port the Prometheus metrics endpoint listens on. |
| `CalculationMode` | `string` (`Default` or `Snapshot`) | `Default` | Selects the virtual parameter calculation strategy. See [Calculation Modes](#calculation-modes) below. |
| `MaxWriteBatchSizeInKb` | `uint` | `100` | Only used when `CalculationMode` is `Snapshot`. Caps the size of each packet written for a virtual — once a virtual's pending samples reach this limit within a batch, they're flushed immediately and accumulation restarts, so no single packet exceeds the limit. Set it to match the Kafka `message.max.bytes` setting. |
!!! info "Single data source"
The VPS only supports a single `DataSource` per instance. To process multiple data sources, deploy separate VPS instances.
## Calculation Modes
`CalculationMode` controls how the VPS decides when to recalculate a virtual parameter, and what happens when a source parameter is slow, quiet, or delivers samples out of order.
=== "Default"
Waits until every source parameter has data covering a given timestamp before calculating, so a virtual's output timestamp is only produced once all of its inputs are aligned. Timestamps that can't yet be aligned are deferred to a later buffering window.
Use Default when a virtual must never be computed from an input that doesn't actually cover its output timestamp — for example, processing recorded or replayed sessions, or sources that can redeliver samples out of order.
=== "Snapshot"
Keeps only the latest known value per source parameter. Any time a source changes, the virtual recalculates immediately using that change together with the latest known value of its other sources (forward-filling the ones that haven't changed). Nested virtuals that depend on the result cascade in the same pass.
Use Snapshot for live streaming: memory use stays flat regardless of session length, and a virtual keeps producing values even while one of its sources ticks slowly. The trade-off is in the warning below.
!!! warning "Snapshot mode never accepts out-of-order data"
If a sample's timestamp is older than the latest value Snapshot has already recorded for that parameter, the sample is rejected rather than retroactively applied. Use `Default` mode for sources that can deliver historical or out-of-order samples.
| | Default | Snapshot |
|---|---|---|
| **Recalculates when** | Every source for a timestamp has arrived | Any one source changes |
| **Memory use** | Grows with source lag over the life of a session | Flat, independent of session length or sample rate |
| **Slow or quiet sources** | Virtual stalls until the slow source catches up | Keeps producing, using the last known value |
| **Out-of-order samples** | Tolerated within the buffering window | Rejected |
```json title="AppConfig.json — enabling Snapshot mode" linenums="1"
"VirtualParameterServiceConfig": {
"CalculationMode": "Snapshot",
"MaxWriteBatchSizeInKb": 100
}
```
!!! note "Add or update — don't replace the whole file"
Add these two settings to your existing `VirtualParameterServiceConfig` section.
## Serilog
Controls application logging. Standard [Serilog configuration](https://github.com/serilog/serilog-settings-configuration) is supported.
!!! warning "Precedence"
The `Serilog` section in `AppConfig.json` takes precedence over command-line arguments (`-l`) and environment variables (`LOG_FILE_PATH`) for log file paths.
### Common Settings
| Setting | Description |
|---|---|
| `MinimumLevel` | Log level: `Verbose`, `Debug`, `Information`, `Warning`, `Error`, `Fatal` |
| `Using` | Serilog sink packages to load |
| `WriteTo` | Array of configured sinks |
### Example: Console + File (Debug Level)
```json
{
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Debug",
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "C:/logs/vps-svc-log.txt"
}
}
]
}
}
```
### Example: File Only (Information Level)
```json
{
"Serilog": {
"Using": ["Serilog.Sinks.File"],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "/logs/vps-svc-log.txt"
}
}
]
}
}
```
---
# Environment Variables
The Virtual Parameter Service supports configuration via environment variables, which are particularly useful when deploying with Docker or Docker Compose.
## Supported Variables
| Variable | Default | Description |
|---|---|---|
| `CONFIG_FILE_PATH` | `Configs/AppConfig.json` | Path to the `AppConfig.json` configuration file. |
| `LOG_FILE_PATH` | `%ProgramData%\Mclaren_Applied_Ltd\VirtualParameterService\Logs\vps-svc-log.txt` | Path to the log file. Must be a full file path ending in `.txt`. |
| `METRIC_PORT` | `10010` | The port on which the Prometheus metrics HTTP endpoint is exposed. |
!!! warning "LOG_FILE_PATH must include a filename ending in .txt"
If the path doesn't end in `.txt`, the service does **not** treat it as a target directory and append `vps-svc-log.txt` inside it. Instead:
- A path with no `.txt` extension but with a parent directory (e.g. `/logs/output` or `/logs`) has its last segment dropped, and `vps-svc-log.txt` is written into what's left of the path (e.g. `/logs/output` → `/logs/vps-svc-log.txt`; `/logs` → the filesystem root).
- A path with no `.txt` extension and no parent directory at all (a bare name like `logs`, relative to the working directory) is treated as a subfolder, with `vps-svc-log.txt` appended inside it.
- A path with some other extension (e.g. `.log`) is rejected outright — the service logs a console warning and reverts to the default path.
Always set `LOG_FILE_PATH` to a full path that ends in a `.txt` filename, e.g. `/logs/vps-svc-log.txt`.
## Precedence Order
- **`CONFIG_FILE_PATH` / `LOG_FILE_PATH`:** the `-c` / `-l` command-line arguments set these environment variables for the process before they're read, so a command-line argument always wins over a manually-set environment variable, which in turn wins over the built-in default. If a `Serilog` section is present in `AppConfig.json`, it takes over logging configuration entirely and `LOG_FILE_PATH` (env var or `-l`) is ignored — see [Logging](logging.md).
- **`METRIC_PORT`:** unlike the two settings above, this also has an `AppConfig.json` equivalent — `VirtualParameterServiceConfig.MetricPort` (see [AppConfig Reference](appconfig-reference.md#virtualparameterserviceconfig)). If `METRIC_PORT` is set, it overrides the `MetricPort` value from `AppConfig.json`.
## Usage with Docker Compose
```yaml
virtual-parameter-service:
image: atlasplatformdocker/virtual-parameter-service-host:latest
ports:
- "10010:10010"
volumes:
- ./virtual-parameter-service/AppConfig.json:/config/AppConfig.json
environment:
- CONFIG_FILE_PATH=/config/AppConfig.json
- LOG_FILE_PATH=/logs/vps-svc-log.txt
- METRIC_PORT=10010
```
## Usage with Docker Run
```bash
docker run -d \
--name virtual-parameter-service \
-p 10010:10010 \
-e CONFIG_FILE_PATH=/config/AppConfig.json \
-e LOG_FILE_PATH=/logs/vps-svc-log.txt \
-e METRIC_PORT=10010 \
-v C:\path\to\AppConfig.json:/config/AppConfig.json \
atlasplatformdocker/virtual-parameter-service-host:latest
```
!!! tip "Environment variables vs command arguments"
When using Docker Compose, environment variables are generally preferred over command arguments (`-c`, `-l`) because only one `command` directive can be specified in the compose file.
---
# Logging
The Virtual Parameter Service uses [Serilog](https://serilog.net/) for structured logging and the standard ASP.NET Core logging framework for host-level messages.
## Application Logging (Serilog)
Application logs capture the operational activity of the VPS — session lifecycle events, parameter processing, errors, and diagnostics.
### Configuration
Serilog is configured via the `Serilog` section in `AppConfig.json`. See the [AppConfig Reference](appconfig-reference.md#serilog) for the full schema.
### Log Levels
| Level | When to Use |
|---|---|
| `Verbose` | Very detailed tracing information. Use only for deep debugging. |
| `Debug` | Internal system events useful for diagnosing problems. |
| `Information` | General operational events (session started, session ended). |
| `Warning` | Unexpected but recoverable situations. |
| `Error` | Failures that prevent part of the system from functioning. |
| `Fatal` | Critical failures that cause the service to stop. |
!!! tip "Recommended production level"
Use `Information` for production deployments. Switch to `Debug` when investigating issues.
### Default Log File Location
When no log path is configured, logs are written to:
=== "Windows"
```
C:\ProgramData\Mclaren_Applied_Ltd\VirtualParameterService\Logs\vps-svc-log.txt
```
=== "Docker"
Specify explicitly via environment variable or command argument:
```
/logs/vps-svc-log.txt
```
## Host Logging (ASP.NET Core)
The underlying .NET host produces its own log messages (startup diagnostics, hosting lifecycle events). These are configured separately via `appsettings.json`.
### Reducing Host Log Noise
By default, `appsettings.json` is configured to minimise host log output:
```json
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft.Hosting.Lifetime": "Warning",
"Microsoft.AspNetCore.Hosting.Diagnostics": "None"
}
}
}
```
This prevents the host framework from flooding the console with startup and request-handling messages, keeping the output focused on VPS-specific logs.
!!! info
`appsettings.json` is located in the root directory alongside the executable. It is separate from `AppConfig.json`.
---
# Troubleshooting & FAQ
Common issues and their solutions when working with the Virtual Parameter Service.
## Common Issues
### VPS container starts but no sessions are detected
??? note "Checklist"
1. **Is ADS running?** Ensure ADS is active and streaming live data.
2. **Is the Bridge Service running?** Verify the Bridge Service container is healthy: `docker ps`.
3. **Is the Bridge Service configured correctly?** See its own [configuration guide](../../../developer-resources/secu4/bridge_service/index.md) for enabling it and setting `BrokerUrl`.
4. **Is the `DataSource` correct?** The VPS's `DataSource` (`AppConfig.json`) must match the DataSource name Bridge Service publishes under.
5. **Is Kafka reachable?** The `BrokerUrl` in `AppConfig.json` must point to a valid, running Kafka broker — the same one Bridge Service is configured to publish to.
6. **Do `StreamCreationStrategy` and `PartitionMappings` match Bridge Service?** If `StreamApiConfig.StreamCreationStrategy` doesn't match Bridge Service's setting, the VPS is looking for data in the wrong place (topics vs. partitions). If it's `1` (partition-based), `PartitionMappings` must match Bridge Service's mapping too — it's ignored for `2` (topic-based).
### Kafka is not initialised in time before the Bridge Service
This is a **known issue** when starting the full Docker Compose stack. The Bridge Service may start before Kafka is fully ready.
??? success "Solution"
Restart the `bridge-service` and `virtual-parameter-service` containers manually:
```bash
docker restart bridge-service
docker restart virtual-parameter-service
```
Alternatively, add health checks and `depends_on` conditions to your `docker-compose.yaml`.
### Prometheus target shows DOWN
??? note "Checklist"
1. **Is `prometheus.yml` configured correctly?** The target must be your machine's IPv4 address, not `localhost`.
2. **Is the VPS running and healthy?** Check `docker ps` for the container status.
3. **Is port 10010 exposed?** Confirm the port mapping with `docker ps` or test with `curl http://YOUR_IP:10010/metrics`.
4. **Firewall?** Ensure port `10010` is not blocked by a firewall rule.
### Metrics endpoint returns an error when running manually
The Prometheus HTTP listener requires **Administrator privileges** when running outside Docker.
??? success "Solution"
Run `MA.DataPlatforms.VirtualParameterService.Host.exe` as Administrator.
### Virtual parameter definitions are failing to build
Check the `vps_virtual_parameter_definition_failed_counter` metric for the count of failures.
??? note "Possible causes"
- **Missing source parameters** — The FDL expression references parameters that are not present in the session.
- **Invalid FDL expressions** — The expression syntax is incorrect or unsupported.
- **Dependency resolution failure** — A virtual parameter depends on another virtual that has not yet been defined.
Check the service logs (set `MinimumLevel` to `Debug` in the Serilog config) for detailed error messages about which definitions failed and why.
### Incomplete virtual parameter definitions (gauge is non-zero)
The `vps_virtual_parameter_definition_incomplete_gauge` indicates virtual definitions waiting for their source dependencies to be defined.
??? note "Explanation"
This is normal during session startup — virtual parameters that depend on other virtuals may be temporarily incomplete until all definitions are received. The gauge should return to `0` once all configuration packets have been processed.
If it remains non-zero indefinitely, check that all required source parameter definitions are being published in the session's configuration packets.
### A virtual parameter's values stop appearing after a source replays old data (Snapshot mode)
??? success "Explanation"
In `Snapshot` calculation mode, a source sample older than the latest value already recorded for that parameter is rejected rather than applied retroactively — this is expected behaviour, not a bug. If your source can redeliver historical or out-of-order samples (e.g. replaying a recorded session), use `CalculationMode: "Default"` instead. See [Calculation Modes](configuration/appconfig-reference.md#calculation-modes).
### Log file is not being created
??? note "Checklist"
1. **Does the Serilog config override the path?** The `Serilog` section in `AppConfig.json` takes precedence over `-l` arguments and `LOG_FILE_PATH` environment variables.
2. **Is the path valid?** The log file must end in `.txt`. If an invalid extension is provided, the service reverts to the default path.
3. **Does the directory exist?** The directory must exist — the service does not create intermediate directories.
4. **Permissions?** The service process must have write access to the target directory.
## FAQ
### Can I run multiple VPS instances for different data sources?
Yes. Each VPS instance supports a single `DataSource`. To process multiple data sources, deploy separate instances with different `AppConfig.json` files, each specifying a different `DataSource` value. Ensure each instance uses a unique `StreamApiPort` and `METRIC_PORT`.
### Which calculation mode should I use?
Use `Snapshot` for live streaming — it keeps memory flat over long-running sessions and keeps producing values even when a source ticks slowly. Use `Default` for replayed/recorded sessions, or any source that can deliver samples out of order, since `Snapshot` rejects out-of-order samples. See [Calculation Modes](configuration/appconfig-reference.md#calculation-modes) for the full comparison.
### Does the VPS process historical sessions?
No. The VPS only processes **live** sessions. Historical sessions and sessions of type `VirtualSession` are automatically filtered out to avoid reprocessing its own output.
### What happens if the VPS goes down during a live session?
The VPS does not persist state between restarts. If the service restarts, it will detect any active live sessions and begin processing them from that point forward. Data generated during the downtime will not be retroactively computed.
### Can I change the buffering window while the service is running?
No. Configuration is loaded at startup. To change `BufferingWindowLengthInMs` or `SlidingWindowPercentage`, update `AppConfig.json` and restart the service.
### What Kafka topics does the VPS use?
The VPS uses the Stream API to manage topic creation and data flow. Topics are created automatically based on the configured `StreamCreationStrategy`. You do not need to manually create Kafka topics.
### How do I verify that virtual data is being written correctly?
1. **Check metrics** — Ensure `vps_virtual_parameter_packet_info_packager_packaged_counter` is incrementing.
---
# Overview
Visualise, compare, and understand high‑frequency telemetry — live or post‑run.
## [ATLAS Viewer](viewer/index.md)
ATLAS Viewer provides a powerful environment for inspecting high‑resolution time‑series data. Built for motorsport engineers, it enables confident, rapid decision‑making through rich visualisation tools and flexible customisation.
### Key Functionality
- Advanced visualisation and layout customisation
- Alarms for rapid event recognition
- Optimised live data viewing
- MATLAB integration
- Compare‑set analysis
- 19 built‑in display types
- Functions and virtual channels
- Secure and reliable data handling
---
# Overview
The Standalone Stream Recorder is a Windows console application that listens to live telemetry published through the [Stream API](../../../developer-resources/secu4/stream_api/index.md) and saves each session to disk, without needing ATLAS Viewer to act as the recorder.
## At a glance
| | |
|---|---|
| **Application** | `MA.DataPlatforms.DataRecorder.Host` |
| **Platform** | Windows (x64) |
| **Input** | A Kafka broker carrying Stream API data |
| **Output** | SSN2 files, or a SQL Race database (SQLite or SQL Server) |
| **Configuration file** | `Config/AppConfig.json`, next to the executable |
| **Logs** | Console and daily rolling files in `logs/` (default) |
## What it does
When the recorder starts it connects to the Kafka broker, waits for sessions published to the configured data source, and records each one as it arrives. When a session ends it waits for the next one.
## Choose your output format
The first decision is `WritingConfig.SessionFormat`:
| Format | Use it when | Also needs |
|---|---|---|
| `SSN2` | You want one SSN2 file per session in a folder. | `WritingConfig.RecordingFolder` |
| `Database` | You want sessions stored in a SQL Race database, and want to load live sessions through the recorder's Server Listener. | `SqlRaceConfig` (connection string, engine, data source, delete option) |
## The three things you must configure
1. **Where to read from** — `StreamApiConfig` (`BrokerUrl`, `StreamCreationStrategy`) and `StreamReadingConfig.DataSource`. These must match the producer's Stream API settings.
2. **Where to write to** — `WritingConfig` and, for `Database`, `SqlRaceConfig`.
3. **Which sessions to record** — `StreamReadingConfig.SessionIdentifierPattern` and `RecordVpsSessions`.
## Next steps
- [Getting Started](getting-started.md) — run the recorder for the first time
- [Configuration Guide](configuration-guide.md) — task-based recipes
- [Configuration Reference](configuration-reference.md) — every field
- [Troubleshooting](troubleshooting.md)
---
# Getting Started
This page takes you from a fresh install to a recorded session.
## Before you begin
- A Windows machine to run the recorder.
- A Kafka broker that a Stream API producer (for example the [Bridge Service](../../../developer-resources/secu4/bridge_service/index.md)) is publishing to.
- The producer's **Stream Creation Strategy**, **broker address** and **data source name**. The recorder must use the same values. See [Server Configuration](../../../developer-resources/secu4/stream_api/reference_docs/configuration/server-config.md).
## 1. Edit AppConfig.json
The recorder reads `Config/AppConfig.json` from the folder containing the executable. This is the shipped file, which records to SSN2 files and works as a starting point:
```json title="AppConfig.json" linenums="1"
{
"$schema": "./AppConfig.schema.json",
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "localhost:9094",
"PartitionMappings": [{}],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"BatchingResponses": false,
"StreamApiPort": 13579,
"Domain": ""
},
"RecordVpsSessions": false,
"WritingConfig": {
"SessionFormat": "SSN2",
"RecordingFolder": "C:\\Standalone Stream Recorder\\SSN2",
"UseTemporaryRecordingFolder": false,
"TemporaryRecordingFolder": "",
"UseStreamApiSessionIdentifier": true,
"UseStreamApiSessionDetails": true
},
"StreamReadingConfig": {
"ReadingMode": "Live",
"DataSource": "Default",
"SessionIdentifierPattern": "*",
"GroupId": ""
},
"SqlRaceConfig": {
"ConnectionString": "DbEngine=SQLite;Data Source=C:\\Standalone Stream Recorder\\stream_recorder.ssndb;PRAGMA journal_mode=WAL;",
"DbEngine": "SQLite",
"DataSource": "C:\\Standalone Stream Recorder\\stream_recorder.ssndb",
"DeleteSessionOnClose": "NoSessionDelete",
"ServerListenerAddress": "127.0.0.1:7300"
},
"MetricsConfig": {
"Port": 10015,
"IsEnabled": false
},
"Serilog": {
"Using": [
"Serilog.Sinks.Console",
"Serilog.Sinks.File"
],
"MinimumLevel": "Information",
"WriteTo": [
{
"Name": "Console"
},
{
"Name": "File",
"Args": {
"path": "./logs/standalone-stream-recorder-.txt",
"rollingInterval": "Day",
"fileSizeLimitBytes": 10485760,
"rollOnFileSizeLimit": true
}
}
]
}
}
```
Change at least `StreamApiConfig.BrokerUrl`, `StreamApiConfig.StreamCreationStrategy` and `StreamReadingConfig.DataSource` to match your producer, and `WritingConfig.RecordingFolder` to a folder you want.
!!! note "Add or update — don't replace the whole file"
To record to a SQL Race database instead of SSN2 files, change only `WritingConfig.SessionFormat` to `"Database"` and make sure the `SqlRaceConfig` values are right for your database. The shipped `SqlRaceConfig` already points at a SQLite file. See the [Configuration Guide](configuration-guide.md#record-to-a-database).
## 2. Start the recorder
Run `MA.DataPlatforms.DataRecorder.Host.exe`. It takes no command-line arguments; all settings come from `AppConfig.json` (and environment variables, see below).
If the configuration is invalid, the recorder logs each problem and does not start. See [Troubleshooting](troubleshooting.md#the-recorder-exits-straight-away).
## 3. Publish a session
Start a session from your Stream API producer on the configured data source. The recorder logs to the console and to `logs/standalone-stream-recorder-.txt`.
## 4. Stop the recorder
Press Ctrl+C in the console window.
## Overriding settings with environment variables
Environment variables are read after `AppConfig.json`, so they override it. Use a double underscore for nesting, for example `WritingConfig__SessionFormat`.
---
# Configuration Guide
Task-based recipes for `Config/AppConfig.json`. Each recipe shows only the settings that change; for every field see the [Configuration Reference](configuration-reference.md).
!!! note "Add or update — don't replace the whole file"
The snippets below are deltas on the shipped `AppConfig.json` shown in [Getting Started](getting-started.md).
## Connect to my Kafka broker
Use this when your producer's Stream API uses a different broker or stream layout from the sample. The recorder must match the producer.
```json title="AppConfig.json (StreamApiConfig)" linenums="1"
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "localhost:9094",
"PartitionMappings": [{}]
}
```
- `StreamCreationStrategy` is `1` (`PartitionBased`) or `2` (`TopicBased`); the names also work.
- `PartitionMappings` is only used with `PartitionBased`; each entry needs a `Stream` name and a `Partition` number.
- If Kafka uses SASL or SSL, see [Kafka Security](../../../developer-resources/secu4/stream_api/reference_docs/configuration/kafka-security.md).
The remaining `StreamApiConfig` fields are documented in [Server Configuration](../../../developer-resources/secu4/stream_api/reference_docs/configuration/server-config.md#configuration-properties).
## Record to SSN2 files
Use this when you want one SSN2 file per session.
```json title="AppConfig.json (WritingConfig)" linenums="1"
"WritingConfig": {
"SessionFormat": "SSN2",
"RecordingFolder": "C:\\Standalone Stream Recorder\\SSN2",
"UseTemporaryRecordingFolder": false,
"UseStreamApiSessionIdentifier": true,
"UseStreamApiSessionDetails": true
}
```
`RecordingFolder` is required for SSN2. It may contain wildcards such as `%r`, `%c`, `%y%m%d` or `$Param$`, which are resolved for each session.
### Write to a temporary folder first
Use this when the final folder is on a slow or shared drive. The file is written to the temporary folder while the session is live, then moved to `RecordingFolder` when it closes.
```json title="AppConfig.json (WritingConfig)" linenums="1" hl_lines="3 4"
"WritingConfig": {
"SessionFormat": "SSN2",
"UseTemporaryRecordingFolder": true,
"TemporaryRecordingFolder": "C:\\Standalone Stream Recorder\\Temp",
"RecordingFolder": "C:\\Standalone Stream Recorder\\SSN2",
"UseStreamApiSessionIdentifier": true,
"UseStreamApiSessionDetails": true
}
```
`TemporaryRecordingFolder` is required when `UseTemporaryRecordingFolder` is `true`.
## Record to a database
Use this when you want sessions in a SQL Race database, or want to load live sessions from the recorder.
=== "SQLite"
```json title="AppConfig.json" linenums="1"
"WritingConfig": {
"SessionFormat": "Database",
"UseTemporaryRecordingFolder": false,
"UseStreamApiSessionIdentifier": true,
"UseStreamApiSessionDetails": true
},
"SqlRaceConfig": {
"ConnectionString": "DbEngine=SQLite;Data Source=C:\\Standalone Stream Recorder\\stream_recorder.ssndb;PRAGMA journal_mode=WAL;",
"DbEngine": "SQLite",
"DataSource": "C:\\Standalone Stream Recorder\\stream_recorder.ssndb",
"DeleteSessionOnClose": "NoSessionDelete",
"ServerListenerAddress": "127.0.0.1:7300"
}
```
=== "SQL Server"
```json title="AppConfig.json" linenums="1"
"WritingConfig": {
"SessionFormat": "Database",
"UseTemporaryRecordingFolder": false,
"UseStreamApiSessionIdentifier": true,
"UseStreamApiSessionDetails": true
},
"SqlRaceConfig": {
"ConnectionString": "server=\\;Initial Catalog=;Trusted_Connection=True;",
"DbEngine": "SQLServer",
"DataSource": "\\",
"DeleteSessionOnClose": "NoSessionDelete",
"ServerListenerAddress": "127.0.0.1:7300"
}
```
Replace the `<...>` placeholders with your SQL Server name, instance and SQL Race database. This example uses Windows authentication (`Trusted_Connection=True`); use whichever SQL Server connection string your SQL Race database requires.
With `Database`, `ConnectionString`, `DbEngine`, `DataSource` and `DeleteSessionOnClose` must all be set, otherwise the recorder will not start. `DbEngine` accepts `SQLite` or `SQLServer`, in any letter case.
The recorder only starts its Server Listener when `SessionFormat` is `Database`.
## Change session identifier or details
Use this when the producer's session identifier or details are not what you want stored.
```json title="AppConfig.json (WritingConfig)" linenums="1" hl_lines="2 3 4 5 6 7"
"WritingConfig": {
"UseStreamApiSessionIdentifier": false,
"SessionIdentifierText": "%y%m%d%H%M%S",
"UseStreamApiSessionDetails": false,
"SessionDetails": {
"MyDetailName": "MyDetailValue"
},
"SessionFormat": "SSN2",
"RecordingFolder": "C:\\Standalone Stream Recorder\\SSN2",
"UseTemporaryRecordingFolder": false
}
```
- `SessionIdentifierText` is required when `UseStreamApiSessionIdentifier` is `false`, and may contain date wildcards.
- `SessionDetails` is a set of text key/value pairs applied when `UseStreamApiSessionDetails` is `false`. `MyDetailName` and `MyDetailValue` are placeholders — use your own.
## Record only some sessions
Use `StreamReadingConfig.SessionIdentifierPattern` to filter by session identifier; `*` records everything.
```json title="AppConfig.json (StreamReadingConfig)" linenums="1"
"StreamReadingConfig": {
"ReadingMode": "Live",
"DataSource": "Default",
"SessionIdentifierPattern": "*"
}
```
`DataSource` must match the data source name set on the producer. When the producer is the Bridge Service, this is the name of the ADS.
## Catchup on missed data
Set `ReadingMode` to `LiveWithCatchUp` to read live data and also catch up on data missed earlier. With `Live` only live data is read.
## Resume recording after a disconnect
Set `StreamReadingConfig.GroupId` so the recorder can continue from where it left off if it disconnects for any reason. Restart the recorder with the same `GroupId` to resume. It may contain only letters, digits, underscores and hyphens.
```json title="AppConfig.json (StreamReadingConfig)" linenums="1" hl_lines="5"
"StreamReadingConfig": {
"ReadingMode": "Live",
"DataSource": "Default",
"SessionIdentifierPattern": "*",
"GroupId": "my-recorder"
}
```
## Record VPS sessions
Set the top-level `"RecordVpsSessions": true`. It defaults to `false`.
## Change the Prometheus metrics port
Use this when the default metrics port clashes with another service. The recorder always exposes Prometheus metrics on `Port`.
```json title="AppConfig.json (MetricsConfig)" linenums="1"
"MetricsConfig": {
"Port": 10015,
"IsEnabled": false
}
```
`Port` must be between 1 and 65535. `IsEnabled` is ignored in this release, so the endpoint is available on `Port` whether it is `true` or `false`.
!!! warning "Administrator rights"
On Windows the metrics endpoint may need the recorder to run as Administrator. If it does not have access, the recorder logs that it is continuing without Prometheus.
## Change logging
Logging is configured by the `Serilog` section. The shipped file logs to the console and to a daily rolling file `./logs/standalone-stream-recorder-.txt` (10 MB limit, rolls on size). If the section is removed, the recorder logs at `Information` level to the console and to `logs/standalone-stream-recorder-.txt`, rolling daily.
---
# Configuration Reference
Every setting in `Config/AppConfig.json`. For task-based examples see the [Configuration Guide](configuration-guide.md).
The shipped `Config` folder includes `AppConfig.schema.json`; the `$schema` entry at the top of `AppConfig.json` lets editors validate and auto-complete the file. Enum settings accept either the name or the number.
The sections `StreamApiConfig`, `WritingConfig`, `StreamReadingConfig`, `SqlRaceConfig` and `MetricsConfig` must be present. `Serilog` is optional.
## Top level
| Key | Type | Default | Description |
|---|---|---|---|
| `RecordVpsSessions` | bool | `false` | Record VPS sessions. |
## StreamApiConfig
Connection settings for the Stream API. The recorder's key settings are below.
| Key | Type | Notes |
|---|---|---|
| `StreamCreationStrategy` | `PartitionBased` (1) / `TopicBased` (2) | Must match the producer. |
| `BrokerUrl` | string | Kafka broker address, for example `localhost:9094`. |
| `PartitionMappings` | array of `{ "Stream": string, "Partition": int }` | Only used with `PartitionBased`. |
All other `StreamApiConfig` settings, including `Security` and the Kafka broker tuning file paths, are described in the [Stream API Server Configuration properties](../../../developer-resources/secu4/stream_api/reference_docs/configuration/server-config.md#configuration-properties). See also [Kafka Security](../../../developer-resources/secu4/stream_api/reference_docs/configuration/kafka-security.md) and [Kafka Broker Tuning](../../../developer-resources/secu4/stream_api/reference_docs/configuration/kafka-broker-tuning.md).
## WritingConfig
| Key | Type | Default | Description |
|---|---|---|---|
| `SessionFormat` | `Database` (0) / `SSN2` (1) | `Database` | Format sessions are recorded in. **Required.** |
| `UseStreamApiSessionIdentifier` | bool | — | Use the session identifier from the Stream API. **Required.** |
| `SessionIdentifierText` | string | empty | Identifier to use instead. Required when `UseStreamApiSessionIdentifier` is `false`; may contain wildcards such as `%y%m%d%H%M%S`. |
| `UseStreamApiSessionDetails` | bool | — | Use session details from the Stream API. **Required.** |
| `SessionDetails` | object of strings | empty | Details to apply when `UseStreamApiSessionDetails` is `false`. |
| `RecordingFolder` | string | empty | Final folder for SSN2 files. Required for `SSN2`; ignored for `Database`. May contain wildcards (`%r`, `%c`, `%y%m%d`, `$Param$`). |
| `UseTemporaryRecordingFolder` | bool | — | Write SSN2 files to `TemporaryRecordingFolder` while live, then move them to `RecordingFolder`. **Required.** |
| `TemporaryRecordingFolder` | string | empty | Required when `UseTemporaryRecordingFolder` is `true` and the format is `SSN2`. |
## StreamReadingConfig
| Key | Type | Default | Description |
|---|---|---|---|
| `ReadingMode` | `Live` (0) / `LiveWithCatchUp` (1) | `Live` | `Live` reads live data only; `LiveWithCatchUp` also catches up on missed data. **Required.** |
| `DataSource` | string | — | Data source to read from, for example `Default`. **Required.** |
| `SessionIdentifierPattern` | string | — | Which sessions to read, for example `*`. **Required.** |
| `GroupId` | string | empty | Group id used to consume the data, so the recorder can continue where it left off after a disconnect. Letters, digits, `_` and `-` only. |
## SqlRaceConfig
Only used when `WritingConfig.SessionFormat` is `Database`. With `SSN2` the section must still be present but may be empty.
| Key | Type | Default | Description |
|---|---|---|---|
| `ConnectionString` | string | — | SQL Race connection string. Required for `Database`. |
| `DbEngine` | `SQLite` / `SQLServer` | — | Case-insensitive. Required for `Database`. |
| `DataSource` | string | — | File path (SQLite) or server address (SQL Server). Required for `Database`. |
| `DeleteSessionOnClose` | `NoSessionDelete` (0) / `RecordedSessions` (1) / `SQLiteDatabase` (2) | — | Whether to delete the session from the database when the recorder closes or new sessions appear. Required for `Database`. |
| `ServerListenerAddress` | string `host:port` | — | Address the Server Listener listens on, used to load live sessions from the recorder. Shipped value: `127.0.0.1:7300`. Only started for `Database`. |
## MetricsConfig
| Key | Type | Default | Description |
|---|---|---|---|
| `Port` | int, 1–65535 | `10110` | Port for Prometheus metrics. The shipped file uses `10015`. |
| `IsEnabled` | bool | `false` | Ignored in this release; the recorder starts the Prometheus endpoint regardless of this value. |
!!! note "Metrics endpoint"
Control the metrics endpoint with `Port` only. `IsEnabled` does not turn it on or off.
## Serilog
Standard [Serilog configuration](https://github.com/serilog/serilog-settings-configuration). The shipped file uses the Console and File sinks with `MinimumLevel` `Information`; the file sink uses `rollingInterval` `Day`, `fileSizeLimitBytes` `10485760` and `rollOnFileSizeLimit` `true`.
## Validation rules
The recorder checks the file at startup and does not start if any rule fails:
- A required section is missing.
- `UseStreamApiSessionIdentifier`, `UseStreamApiSessionDetails`, `UseTemporaryRecordingFolder` or `SessionFormat` is not set.
- `SessionFormat` is `SSN2` and `RecordingFolder` is empty, or `UseTemporaryRecordingFolder` is `true` and `TemporaryRecordingFolder` is empty.
- `UseStreamApiSessionIdentifier` is `false` and `SessionIdentifierText` is empty.
- `SessionFormat` is `Database` and `ConnectionString`, `DbEngine`, `DataSource` or `DeleteSessionOnClose` is not set.
- `DbEngine` is not `SQLite` or `SQLServer`.
- `ServerListenerAddress` is set to a non-empty value that does not match `host:port`. An empty or non-IP value does not stop startup; see [Troubleshooting](troubleshooting.md).
- `MetricsConfig.Port` is outside 1–65535.
- `GroupId` contains characters other than letters, digits, `_` or `-`.
---
# Troubleshooting
## The recorder exits straight away
**Symptom:** the console logs `Invalid AppConfig.json configuration: ...` followed by `AppConfig.json contains invalid configuration. See the log for details. The application will not start.`
**Cause:** a [validation rule](configuration-reference.md#validation-rules) failed. Each message names the setting, for example:
- `SqlRaceConfig section is missing from AppConfig.json.`
- `WritingConfig.RecordingFolder must be set when WritingConfig.SessionFormat is SSN2.`
- `SqlRaceConfig.ConnectionString must be set when WritingConfig.SessionFormat is Database.`
- `SqlRaceConfig.DbEngine must be either 'SQLite' or 'SQLServer'.`
- `MetricsConfig.Port must be between 1 and 65535.`
- `GroupId must only contain alphanumeric characters, underscores, or hyphens.`
**Fix:** correct the named setting and restart. Keep `"$schema": "./AppConfig.schema.json"` at the top of the file to get editor warnings before you run.
## "Server Listener will NOT be started"
**Symptom:** the log contains `Failed to parse ServerListenerAddress '...'. Server Listener will NOT be started.`
**Cause:** `SqlRaceConfig.ServerListenerAddress` is empty, or it is not an IP address and port. A hostname such as `localhost:7300` is not accepted here. The recorder keeps running without the Server Listener.
**Fix:** use an IP address and port, for example `127.0.0.1:7300`. A value that is not in `host:port` form at all stops startup instead; see [Validation rules](configuration-reference.md#validation-rules).
## No Prometheus metrics
**Symptom:** the log says `Need Administrator privilege to run Prometheus. continue without Prometheus`.
**Cause:** Windows denied the recorder permission to listen on the metrics port.
**Fix:** run the recorder as Administrator, or do without metrics.
## Nothing is recorded
Check that the recorder matches the producer:
- `StreamApiConfig.BrokerUrl` and `StreamCreationStrategy` are the same as the producer's.
- `StreamReadingConfig.DataSource` is the producer's data source name.
- `StreamReadingConfig.SessionIdentifierPattern` matches the session identifier (`*` matches everything).
- For VPS sessions, `RecordVpsSessions` is `true`.
The log file (`logs/standalone-stream-recorder-.txt` by default) shows what the recorder is doing.
---
# Overview
The ATLAS Viewer is a core component of the ATLAS ecosystem, designed for the visualisation and analysis of telemetry data. It enables users to interact with both live and historical data streams, offering real-time insights and deep analytical capabilities tailored for motorsport and other telemetry-intensive applications.
Key features include:
- **Live Telemetry Access**: Monitor performance data in real time, whether trackside or remotely.
- **Customised Analysis**: Analyse data specific to individual vehicles or subsystems.
- **Historical Replay**: Revisit and study past sessions using stored telemetry files.
- **Flexible Integration**: Supports a wide range of data formats including proprietary (.ssn2), SQL Race databases, CSV, MATLAB, and Parquet.
- **Automation Support**: Through the ATLAS Automation API, users can automate session loading, display configuration, and parameter management using .NET-compatible languages like C#, and MATLAB.
The client operates as a plugin-based composite application, allowing extensibility and integration with custom display modules. It is optimised for performance and supports service-oriented architecture principles to streamline user workflows. For more information on how to create your own plugins read the [Display API Documentation](../../../developer-resources/atlas/display-api/index.md)
---
# Getting Started
## Launching ATLAS
To start ATLAS, if installed in the default location:
* Click Start > All Programs > McLaren Applied Technologies> ATLAS
A new Workbook is opened with a single empty Page by default.

## Adding a Licence
Use the Licence Manager utility to display and modify licence information. Licence codes may be added after ATLAS has been installed.
The default location on the Start menu is: All Programs > McLaren Applied Technologies > Licence Manager.

## Using ATLAS
The Main Window of ATLAS is displayed when you start the program and open a Workbook. It is highly customisable but has a number of key features by default as shown below.

### [Workbooks and Pages](system-operation/workbook.md)
Workbooks in ATLAS define the layout and positioning of elements on the screen. Each Workbook contains one or more Pages, and each Page can host multiple Displays. Workbooks are saved as `.wbkx` files, which store the formatting, size, and position of Displays, allowing users to create customized workspaces.
!!! note
Data files such as Compare Sets, Session data, Bit Config Files, Functions files, Alarm Files, Circuit Display Definition files, SurfaceMap Display Definition files, and PCU Dash Display RAW CAN files are not stored in `.wbkx` files but are automatically opened by the Workbook. If these files are unavailable, Displays will appear empty.
When ATLAS starts or a new Workbook is opened, it includes one Page by default. Users can select only one Page at a time, but multiple Pages can be viewed by floating and arranging them within a Workbook. Each Display on a Page can show data from different Compare Sets.
The Page Bar, located at the top of the Main Window, displays tabs for each Page in the Workbook. If there are too many tabs to fit, horizontal scroll arrows appear. Pages can be selected by clicking on a tab or using the Page Up/Page Down keys.
Right-clicking a Page tab opens a menu with options to:
- **Set:** Switch or remove the Compare Set associated with the Page. Each Set is color-coded.
- **No Association:** Remove the link to the current Compare Set.
- **Lock to Current Association:** Lock the Page to the current Compare Set.
- **Title:** Edit the Page name.
- **Page Colour:** Underline the tab with a selected color.
- **New:** Add a new Page.
- **Paste:** Paste a copied Display to the Page.
- **Import Display:** Import a saved Display to the Page.
- **Duplicate:** Duplicate the Page and its Displays within the Workbook.
- **Export:** Export the Page for use in other Workbooks.
- **Close:** Close the Page tab.
- **Close Others:** Close all other Page tabs.
- **Close Tab Group:** Close all Pages.
- **Float:** Float the Page into a movable window.
- **Float Page Group:** Float the Page Group into a movable window.
- **Pin Tab:** Toggle the pin status of the tab.
- **New Horizontal Tab Group:** Add a horizontal Page tab group.
- **New Vertical Tab Group:** Add a vertical Page tab group.
### [Sessions](handling-data/sessions/index.md)
Use the Session Browser (*CTRL + L*) to record a new session or load an existing one. The Session Browser allows you to define different sets of data to use across the Workbook. Sessions, either Live or Historical, may be combined into a single set using Compare or Append mode.
Add historical data to the set from the Sources tab or directly from files. The preview pane displays detailed session information to help identify the session you need.
Access live data via Recorders. A Recorder streams raw telemetry data, and several types are available depending on the data source, protocol, and system architecture.

### [Displays](displays/index.md)
Once data has been added, begin building your Workbook by adding Displays to Pages. Multiple types of Displays are available, each of which can be customised to meet specific requirements. Displays may be docked in various layouts to optimise visibility across the Workbook.
For detailed information on types of Displays, shortcuts and different display options refer to the embedded documentation: Help > View Help (Preview) (*F1*).
### [Parameters](handling-data/parameters/index.md)
Use the Parameter Browser (*P*) to select one or more parameters to display. Double-click a parameter or drag and drop it onto the Display. To remove a parameter, click on it and press *DELETE*.
Once parameters are visible in the Display, customise the visual presentation using the Display Properties (*D*) panel. Key display options are also available by right-clicking anywhere on the Display.

---
# Mouse Actions
A mouse with a scroll-wheel is recommended, though many actions have [Keyboard Shortcuts](keyboard.md).
{class="mouse-img"} Use the scroll wheel to zoom in and out on a Waveform Display or the Bing Map Display.
{class="mouse-img"} Left click to select menu items and click buttons.
{class="mouse-img"} Right click to display context sensitive (pop-up) menus where available.
{class="mouse-img"} Hold both buttons and move the mouse left or right to scroll a Waveform Display left or right.
{class="mouse-img"} Left click, hold and drag to scroll the time reference indicator on a Timeline in the direction of the mouse movement.
This action can also be used to drag and drop parameters.
{class="mouse-img"} Right click, hold and drag to select a section of a waveform which you can then choose to zoom in on by selecting Zoom from the pop-up menu.
---
# Keyboard Shortcuts
## Main Window
| Shortcut | Description |
| ------------------------------------------------------------|---------------------------------------------------------------------------------------- |
| ++ctrl+l++ | Open Session Browser |
| ++p++ or ++insert++ | Open Parameter Browser |
| ++ctrl+q++ | Quick-Access Assistant |
| ++ctrl+n++ | New workbook page |
| ++page-down++ | Next workbook page |
| ++page-up++ | Previous workbook page |
| ++ctrl+tab++ | Cycle between displays (forwards) |
| ++ctrl+shift+tab++ | Cycle between displays (backwards) |
| ++ctrl+enter++ | Toggles full screen mode |
| ++ctrl+shift+r++ | Rebuild all functions |
| ++ctrl+e++ | Show the Data Export Tool |
### Saving and Loading
| Shortcut | Description |
| ------------------------------------------------------------|---------------------------------------------------------------------------------------- |
| ++ctrl+o++ | Open a workbook |
| ++ctrl+s++ | Save a workbook |
| ++ctrl+alt+s++ | Save a workbook as... |
| ++ctrl+shift+c++ | Copies a Session Reference to the clipboard |
| ++ctrl+shift+l++ | Load a Session Reference from the clipboard |
### Quick-Access
| Shortcut | Description |
| ------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| ++ctrl+q++ | Cycle between Quick-Access features |
| ++down++ | Select the next Quick-Access item |
| ++up++ | Select the previous Quick-Access item |
| ++enter++ | Select the current Quick-Access item |
| ++escape++ | Close the Quick-Access Assistant |
### Associating Compare Sets
| Shortcut | Description |
| ------------------------------------------------------------------|---------------------------------------------------------------------------------------- |
| ++shift+1++ … ++shift+9++ | Select the Compare Set for the _active display_ |
| ++shift+0++ | Select the Compare Set for the _active display_ (set 10*) |
| ++shift++ + ++minus++ | Select the Compare Set for the _active display_ (set 11) |
| ++shift++ + ++equal++ | Select the Compare Set for the _active display_ (set 12) |
| ++shift+backspace++ | Select the Compare Set for the _active display_ (set 13) |
| ++shift++ + ++semicolon++ | Select the Compare Set for the _active display_ (set 14) |
| ++shift++ + ++single-quote++ | Select the Compare Set for the _active display_ (set 15) |
| ++shift++ + ++comma++ | Select the Compare Set for the _active display_ (set 16) |
| ++shift++ + ++period++ | Select the Compare Set for the _active display_ (set 17) |
| ++shift++ + ++slash++ | Select the Compare Set for the _active display_ (set 18) |
| ++shift+tab++ | Select the Compare Set for the _active display_ (set 19) |
| ++shift+capital++ | Select the Compare Set for the _active display_ (set 20)
| ++ctrl+1++ … ++ctrl+9++ | Select the Compare Set for all displays on the _active page_
| ++ctrl++ + same order of keyboard characters listed above | Select the Compare Set for all displays on the _active page_ (sets 10-20) |
| ++ctrl+f1++ … ++ctrl+f9++ | Select the Compare Set for all displays in the _active page group_
| ++ctrl+shift+1++ … ++ctrl+shift+9++ | Select the Compare Set for _all displays_
| ++ctrl+shift++ + same order of keyboard characters listed above | Select the Compare Set for _all displays_ (sets 10-20) |
| ++shift+delete++ | Clears the Compare Set for the _active display_ |
| ++ctrl+delete++ | Clears the Compare Set for all displays on the _active page_ |
| ++ctrl+shift+delete++ or ++ctrl+alt+shift+delete++ | Clears the Compare Set for all displays in the active _page group_ |
## Timeline and Navigation
| Shortcut | Description |
| ----------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| ++plus++ | Zoom in |
| ++minus++ | Zoom out |
| ++ctrl+shift+f++ | Select all laps |
| ++ctrl+shift+t++ | Select all timed laps (excludes in/out laps) |
| ++home++ | Move to start of session |
| ++end++ | Move to end of session |
| ++right++ | Move to next sample timestamp |
| ++left++ | Move to previous sample timestamp |
| ++ctrl+shift+right++ | Move to next lap |
| ++ctrl+shift+left++ | Move to previous lap |
| ++ctrl+f++ | Move to fastest lap |
| ++ctrl+bracket-right++ | Go to next occurrence of event |
| ++ctrl+bracket-left++ | Go to previous occurrence of event |
| ++ctrl+alt+right++ | Go to next signal change |
| ++ctrl+alt+left++ | Go to previous signal change |
## Displays
| Shortcut | Description |
| ------------------------------------------------------------|---------------------------------------------------------------------------------------- |
| ++ctrl+q++ | Quick-Access Parameter or Function |
| ++p++ or ++insert++ | Insert Parameter |
| ++del++ | Delete Parameter |
| ++d++ | Show the Display Properties |
| ++ctrl+tab++ | Cycle between displays (forwards) |
| ++ctrl+shift+tab++ | Cycle between displays (backwards) |
| ++ctrl+f10++ | Toggles the current titlebar on/off |
| ++ctrl+f11++ | Hides all titlebars |
| ++ctrl+f12++ | Shows all titlebars |
### Circuit Display
| Shortcut | Description |
| ------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| ++ctrl+alt+t++ | Generate circuit from the current lap |
### Histogram Display
| Shortcut | Description |
| ------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| ++k++ | Cycle the X axis mapping instance |
| ++ctrl+shift+k++ | Set the X axis mapping instance for all displays |
| ++ctrl+k++ | Set the X axis mapping instance for all page displays |
### Numeric Display
| Shortcut | Description |
| ------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| ++ctrl+c++ | Copy to Clipboard |
| ++ctrl+a++ | Select All |
### Scatterplot Display
| Shortcut | Description |
| ------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| ++r++ | Reference cursor |
| ++h++ | Hide/show cursor |
| ++t++ | Hide/show parameter trace |
| ++plus++ | Zoom in |
| ++minus++ | Zoom out |
| ++ctrl+z++ | Undo zoom |
| ++ctrl+alt+z++ | Undo all zooms |
| ++ctrl+y++ | Redo zoom |
| ++ctrl+p++ | Print |
| ++ctrl+shift+p++ | Print Preview |
### Waveform Display
| Shortcut | Description |
| ------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| ++r++ | Reference cursor |
| ++c++ | Cross-hair cursor |
| ++g++ | Gradient cursor |
| ++v++ | Value cursor |
| ++h++ | Hide cursor |
| ++t++ | Hide/show parameter trace |
| ++ctrl+a++ | Selects legend items |
| ++ctrl+c++ | Copies selected legend items to clipboard |
| ++k++ | Cycle the X axis mapping instance |
| ++ctrl+shift+k++ | Set the X axis mapping instance for all displays |
| ++ctrl+k++ | Set the X axis mapping instance for all page displays |
| ++f++ | Set zero time reference for TimeDiff |
| ++e++ | Show delta statistics |
| ++ctrl+t++ | Show the display docking area |
| ++s++ | Show statistics |
| ++m++ | Show minimum statistics |
| ++x++ | Show maximum statistics |
| ++n++ | Show mean statistics |
| ++q++ | Show standard deviation statistics |
| ++plus++ | Zoom in |
| ++minus++ | Zoom out |
| ++ctrl+z++ | Undo zoom |
| ++ctrl+alt+z++ | Undo all zooms |
| ++z++ | Zoom box |
| ++escape++ | Cancel zoom box |
| ++ctrl+p++ | Print |
| ++ctrl+shift+p++ | Print Preview |
### Known issue (Windows 11)
The command to switch a page group to the 10th compare set (++ctrl+shift+0++) may not work on some Windows 11 systems due to a system-level language hotkey using the same combination. To restore the shortcut, disable the language hotkeys:
- Open Windows Settings > Typing > Advanced keyboard settings.
- Click "Input language hot keys".
- Select "Between input languages" or "Keyboard layout" and click "Change Key Sequence".
- Set "Switch keyboard layout" to "Not assigned".
This change removes the OS-level binding that can block ++ctrl+shift+0++, allowing the application shortcut to work as expected.
Also to note, for switching to set 15, on US keyboards you'll need to use the # key instead of ++single-quote++.
---
# Options
SessionState Options Screen
The Options screen lets you view and change various ATLAS settings. These settings apply at a system level and are stored with the ATLAS installation, not on a Workbook basis.
To view the Options screen select Tools > Options.

## General
| Option Name | Description | Area | Default/Notes |
|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|------------------------------------------------------------------------------------------------|
| Function Folder(s) | Specifies the directory where all user-defined Functions are loaded from and saved to. You can edit this path directly or browse to a folder. Changing this affects where ATLAS looks for and stores custom function scripts, which are used for data processing or automation. | Functions | C:\Users\USERNAME\Documents\McLaren Electronic Systems\SQL Race\Functions |
| Constants Folder Location | Sets the folder for loading and saving Constants, which are reusable values or parameters used in calculations or scripts. Like the Functions folder, this can be edited or browsed to. Ensures all constants are centralised for easier management and sharing. | Functions | C:\Users\USERNAME\Documents\McLaren Applied Technologies\ATLAS 10\Constants |
| Resolve without App Name | When enabled, allows parameters to be loaded from sources that use different Application Groups, so you can see and use channels even if the application names don’t match exactly. Useful for working with data from multiple sources or legacy systems. | Data | Off by default |
| Parameter Properties in Compare mode| Determines how parameter properties (such as units, scaling, etc.) are inherited when comparing multiple sessions: • **Primary Session**: Secondary sessions inherit properties from the primary session. • **User Defined**: Local changes to secondary session properties are retained. • **Default Data**: Properties stored within each session are loaded. Useful for ensuring consistency or flexibility in data comparison. | Data | User selects mode |
| Move to Next/Previous Signal Change Parameter | Selects the parameter whose value changes are used by the Move to Next/Previous Signal Change actions (toolbar and Ctrl+Alt+Left/Right). | Data | `NGear:Chassis` |
| Recent Workbook Max Count | Sets the maximum number of recent Workbooks shown in the File > Recent Workbooks menu, making it easier to quickly reopen frequently used files. | Workbook | 15 |
| Load Sessions with Workbooks | If enabled, when you open a Workbook, all sessions that were loaded when it was last closed are automatically reloaded. This helps restore your previous working context. | Workbook | Checkbox |
| Open Last Workbook when Starting | When enabled, ATLAS will automatically reopen the last opened or saved Workbook at startup, streamlining workflow continuity. | Workbook | Checkbox |
| Auto Fit Laps | In Compare Sets with multiple laps, this option aligns the start and end of each lap on the X-axis in the Waveform Display, making it easier to visually compare laps of different durations. | Workbook | Checkbox |
| Auto Fit Limit % | Sets the maximum percentage difference between laps that Auto Fit will stretch data to match. Prevents excessive distortion when aligning laps. Default is 5%. | Workbook | 5% |
| Load Recorders From | Determines whether saved Recorder configurations are loaded from the Workbook (unique to each file) or from a Local Configuration file (shared across all Workbooks). Useful for managing how recording setups are reused. | Workbook | LocalConfiguration |
| Remove unused recorders from Workbook| If enabled, removes any Recorders when saving the Workbook that are not used in any Sets. Helps keep the Workbook tidy of unused old Recorders. | Workbook | Checkbox |
| Remove set when last session unloaded| If enabled, deletes the current set when the last session is removed from it (except the final set). Helps keep the workspace tidy by removing empty sets. | Workbook | Checkbox |
| Workbook Folder Enabled | Allows you to specify a dedicated folder for storing Workbook files, improving organisation and backup management. | Workbook | Checkbox |
| Workbook Backups Enabled | Enables automatic, regular backups of your Workbook files to a specified folder, providing data recovery in case of corruption or accidental changes. | Workbook | Checkbox |
| Workbook Backups Folder | Sets the directory where Workbook backup files are stored. You can edit or browse to this folder. Ensures backups are kept in a known, safe location. | Workbook | C:\Users\USERNAME\Documents\McLaren Applied Technologies\ATLAS 10\Automatic Workbook Backups |
| Number of backups to keep per workbook| Specifies how many backup copies of each Workbook are retained. When the limit is exceeded, the oldest backups are deleted. Helps manage disk space while ensuring recovery options. | Workbook | 5 |
| Waveform Data Request | Sets the frequency (in Hz) at which data is requested for Waveform displays. Higher rates provide more real-time updates but may use more resources. | Performance | 0.5–10 Hz (default 5 Hz) |
| Backfill Request | Determines the time window (in seconds) for backfilling gaps in live telemetry data on the Waveform. Ensures continuity in data display during brief interruptions. | Performance | 1–10 sec (default 3 sec) |
| Statistics Data Request | Sets the update rate for statistics (Lap, Display, Session, Reference). Options are Low, Medium, or High, balancing performance and responsiveness. | Performance | Medium |
| Waveform Display Refresh | Controls how often the Waveform Display is refreshed (in Hz). Higher rates give smoother updates but may impact performance. | Performance | 10–20 Hz (default 15 Hz) |
| Scatterplot Data Request | Sets the frequency (in Hz) for requesting data for Scatterplot displays. Balances update speed and resource usage. | Performance | 0.5–5 Hz (default 2.5 Hz) |
| Scatterplot Display Refresh | Determines how often the Scatterplot Display is refreshed (in Hz). | Performance | 10–20 Hz (default 10 Hz) |
| Renderer | Selects the rendering mode for ATLAS: • **Hardware Accelerated**: Uses GPU for best performance. • **Balanced**: Mix of performance and compatibility. • **Software**: CPU rendering, recommended for virtual machines or systems without suitable GPU. | Performance | Hardware Accelerated/Balanced/Software |
| Tcp Port Number | Sets the TCP port for the Automation API server, which allows external clients to connect and control ATLAS programmatically. Change if the default port is in use. | Automation Service | 9089 |
| Authorization Port Number | For users with an RTA License, sets the OAuth 2.0 port for authentication. Adjust if needed for network or security requirements. | Service Connections | 59511 |
| Tab Side | Changes which side of the screen the workbook page tabs are displayed (e.g., top, bottom, left, right), allowing for custom workspace layouts. | Appearance | - |
| Tab Overflow | Determines how workbook page tabs behave when there are too many to fit on the screen: • **Menu**: Overflow tabs in a dropdown. • **Shrink**: Shrinks tabs to fit. • **ShrinkWithMenu**: Shrinks tabs and uses a menu for overflow. • **Scroll**: Adds scroll arrows. • **ScrollWithMenu**: Combines scroll and menu. | Appearance | - |
| Extension | Defines the file extension for text files imported as sessions (e.g., .csv, .txt, .asc). Must include the dot. | Text Session Format | - |
| Total Header Line | Sets the number of header lines in the imported text file. Must be at least one; extra lines can contain metadata or comments. | Text Session Format | - |
| Parameter Line | Specifies the line number where parameter definitions start in the text file. | Text Session Format | - |
| Group Line | Indicates the line number for parameter groups. Set to 0 if not used. | Text Session Format | 0 if not used |
| Date Exists | Specifies whether each data line includes a date column. If enabled, the first column is the date, second is the timestamp. | Text Session Format | - |
| Time Format | Sets the format for timestamps in imported text files (e.g., DateTime, Milliseconds, Seconds, Time). | Text Session Format | - |
| Delimiter | Sets the character used to separate columns in the text file (Tab, Space, Comma, Semicolon). | Text Session Format | - |
| Unit | Specifies the line number where units are defined in the text file. | Text Session Format | - |
| Lap Marker | Sets the parameter name used to identify laps in the text file. When the value changes, ATLAS creates a lap marker. | Text Session Format | - |
| Mapping Mode | Lets you manage the mapping mode for the X-axis in Waveform Displays (e.g., Time or Distance). Plugins can add new modes. You can reorder, add, or remove mapping plugins. | X Axis Mapping | Controlled by plugins |
| Crash Report Folder | Sets the directory where crash reports are saved. You can edit or browse to this folder. Used for diagnostics and troubleshooting. | Crash Reports | C:\Users\USERNAME\Documents\McLaren Applied Technologies\ATLAS 10\Crash Reports |
| Number of crash reports to keep | Specifies how many crash reports are retained in the folder. Oldest reports are deleted when the limit is exceeded. | Crash Reports | 10 |
| Watchdog TCP Port | Sets the TCP port for the ATLAS Watchdog, which monitors application health and can generate crash reports. | Crash Reports | 9092 |
## Diagnostics
| Option Name | Description | Area | Default/Notes |
|-------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|------------------------------------------------------------------------------------------------|
| Application Insights (Allow collection of Metrics and Error data) | When enabled, this option allows ATLAS to share performance metrics and logged exceptions with McLaren Applied for product improvement and troubleshooting. No personally identifiable information (PII) is shared. This helps McLaren Applied monitor application health and usage trends, but preserves user privacy. | Metrics | Off by default. Toggle as needed for support or analytics. |
| ATLAS Logging Level | Sets the level of detail for log messages written to ATLAS log files. Each level includes all levels below it: • **Trace**: Extremely detailed logs, including code execution paths and algorithm steps. Intended for development or deep troubleshooting. • **Debug**: Detailed logs for debugging, including variable states and configuration. • **Info**: Logs significant events indicating normal operation (e.g., service start/stop). • **Warn**: Logs events that could become issues if not addressed (e.g., high resource use). • **Error**: Logs significant problems that affect operations but do not stop the application (e.g., failed API calls). • **Off**: Disables logging entirely. | Logging | Default is Info. Trace is only recommended for support/development. |
| Logfile Path | Specifies the folder where ATLAS log files are stored. You can set this to any accessible directory. Useful for organising logs or directing them to a monitored location for support. | Logging | User-defined. |
| Max Archive Files | Sets the maximum number of archived log files to keep alongside the current active log file. When the limit is reached, the oldest archives are deleted. This helps manage disk space while retaining recent log history for troubleshooting. | Logging | Default is 9. |
| Archive Above Size | Sets the file size threshold (in bytes) at which a log file is archived and a new log file is started. Prevents log files from growing too large. Default is 10MB (10,485,760 bytes). | Logging | Default is 10MB (10485760 bytes). |
| SQL Race Logging Level | Sets the logging level specifically for SQL Race data, using the same levels as ATLAS Logging Level (Trace, Debug, Info, Warn, Error, Off). Allows for separate control of logging detail for SQL Race operations, which may be useful for diagnosing database-related issues. | Logging | Default is Info. Trace is only recommended for support/development. |
## Plugins
| Option Name | Description | Area | Default / Limits / Notes |
|-----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Alarm library | Folder location of the alarm library used by ATLAS. | Alarms | Default: `C:\Users\[username]\Documents\McLaren Applied Technologies\ATLAS 10\Alarms`. Editable path. |
| Additional Alarm File | Path to an extra alarm definition file to load alongside the main alarm library. | Alarms | Editable file path. |
| Alarm Popup Mode | Controls how alarm pop‑ups are shown: **Per Alarm**, **Per Occurrence**, or **Shared**. | Alarms | Choose one of the three modes. |
| Delayed Range | Sets the look‑back time window for alarms “behind the leading edge.” | Alarms | Default 3 s; min 2 s; max 5 min. **Note:** Increasing above default can degrade live telemetry performance. |
| Should Auto‑Refresh | Enables/disables automatic refresh of the Session Browser’s session list. | Session Browser | Disabled by default. |
| Auto Refresh Interval (seconds) | Interval, in seconds, for automatic Session Browser refresh when enabled. | Session Browser | Default 300 s. |
| Filters Display Limit | Maximum number of filter results returned in Session Browser. | Session Browser | Default 100. |
| Session Query Result Limit (Sessions) | Maximum number of sessions returned when databases/folders are selected in Session Browser. | Session Browser | Default 1000. |
| Circuits Location | Directory containing circuit definition files (`*.ckt`/`*.cktx`). | Circuit Display | Editable directory; example shown `T:\Circuits`. |
| X‑Axis Mapping | Which X‑axis mapping the Circuit Display uses (e.g., time/distance); mappings are configured under **Options → X Axis Mapping**. | Circuit Display | Example shown: `DistanceModeMapping (sLap)`. |
| Circuit Location Parameter Name | Parameter used to define circuit location. | Circuit Display | Default: `NEventLocation`. |
| End of Straight Parameter | Parameter used for “End of Straight” calculations. | Circuit Display | Default: `vCar:Chassis`. |
| Global Circuit Definition | Choose a specific global circuit definition from the Circuits location, or allow automatic selection on session load. | Circuit Display | Auto/manual selection. |
| Circuit Generator — Parameters | Parameters the generator uses to infer circuit size/shape. | Circuit Display | Defaults: `vCar:Chassis` (speed) and `gLat:Chassis` (lateral‑G). |
| Circuit Generator — Shape/Invert/Rotation | Controls for the generated circuit’s shape (e.g., circle/figure eight/open), inversion, rotation. | Circuit Display | Editable controls. |
| Circuit Generator — Generation Settings | Gain and Offset applied to generated circuits. | Circuit Display | Tunable numeric values. |
| Bit Configuration File | File path to the Bit Display configuration file used by the Bit Display plugin. | Bit Display | Editable file path. |
| Maximum Number of Parameters | Caps the number of parameters that can be added to a Scatterplot Display. | Scatterplot Display | Recommended: **24**. Increasing may cause performance issues. |
| Session Details Tooltip Limit | Max number of session‑detail properties that can be selected/saved for the F1 Timeline’s Session Details tooltip. | F1 Timeline | Default 5; min 0; max 20. |
| Snapshots Directory | Directory where Summary Display snapshot images (from the Snapshot generator) are stored. | Summary Display | Editable directory. |
| Hide Windows cursor when dragging waveform | Hides the Windows cursor while left‑click + dragging the time/distance cursor on the Waveform Display. | Waveform Display | Toggle option. |
| Enable Grid Scrolling | Waveform gridlines scroll with the leading edge during live or historical replay. | Waveform Display | Toggle option. |
| Event Tracking Mask | Selects an event for use with Next/Previous event keyboard shortcuts on the Waveform. | Waveform Display | Choose event parameter. |
| Maximum Number of Parameters | Caps parameters that can be added to a Waveform Display. | Waveform Display | Recommended: **100**. Increasing may cause performance issues. |
| Date / Data Notation | For sessions spanning multiple days, controls how the date appears in the Waveform title bar (e.g., “Day 1” vs `DD/MM/YYYY`). | Waveform Display | Example default shown: `DayNumber`. |
| Context Menu & Key Shortcut Statistic Level | Sets whether Right‑click and keyboard‑shortcut statistics apply at **Lap**, **Session**, or **Display** level. | Waveform Display | Example default shown: `Lap`. |
| Override … for Reference Cursor | Allows the **Reference Cursor** level (applied with `R`) to override the chosen Context Menu/Shortcut statistics level. | Waveform Display | Toggle option. |
| Raw Files Path | Folder path for RAW files used by the PCU Dash Display. | PCU Dash Display | Example shown: `T:\PCU8`. |
| LED Status Light parameter name | Parameter used by PCU Dash for the LED Status Light. | PCU Dash Display | Example shown: `NLEDStatusAll`. |
| Auto map CAN parameters (by name) | Automatically maps CAN parameters by matching names, simplifying setup. | PCU Dash Display | Toggle option. |
| CAN Bus Identifier | Identifier number for the CAN bus used by the PCU Dash Display. | PCU Dash Display | Example shown: `7`. |
## Recorders
| Option Name | Description | Area | Default / Notes |
|-------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|----------------------------------------------------------------------------------------------------------|
| Server Listener IP | IP address for the SQLRace database server listener, used for remote access and live data recording. | SQLRace | Default: 127.0.0.1 |
| Server Listener Port | Port number for the SQLRace database server listener. | SQLRace | Default: 7381 |
| Data Server buffer size (MB) | Size of the storage buffer in the client for incoming data. Larger values help prevent data loss if network communications are poor. | Recording | Default: 20MB |
| Data Server connection timeout (ms) | Time ATLAS waits for data from a data server before stopping recording. | Recording | Default: 20000ms |
| Data Server retries enabled | Allows the client to retry loading data from the network if enabled. | Recording | Default: Unchecked |
| Data Servers | List of ATLAS Data Server names and corresponding ports (format: {Server:Port}). | Recording | Default: Empty |
| Server auto-refresh frequency (ms) | Interval between refreshing the list of current data servers (0 disables). | Recording | Default: 2000ms |
| Server auto-refresh reply timeout (ms) | Time before a data server is deemed offline if no activity is detected. | Recording | Default: 100ms |
| Server Reply Timeout (ms) | Time ATLAS waits for a reply from a data server. | Recording | Default: 3000ms |
| Timeout for searching for Data Servers (ms)| Time allowed to find data servers. | Recording | Default: 3000ms |
| Wide Band local address | Specifies which network card to use for sending/receiving data; shows all available IP addresses. | Recording | Default: ANY |
| Auto-Dismiss Config Search Box | Automatically closes the config search box if checked. | General | Default: Checked |
| Auto Increment Run Number | Automatically increments the session number for sequential recordings (e.g., R1, R2, ...). | General | Default: Unchecked |
| Auto Record Connection Check Interval (ms)| Time ATLAS waits before stopping automatic recording. | General | Default: 1000ms |
| Default disabled 'Still Processing Parameters' to continue | If enabled, ATLAS will auto-select continue/cancel if a recording is running when closing and the dialog is disabled. | General | Default: Unchecked |
| DTV offload exclusion list | Comma-separated list of DTVs to exclude from offload at end of recording. Supports formats: application-name, unit-name.application-name, unit-name.* | General | Default: Blank |
| DTV rename cached files | If checked, cached DTV files not uploaded will include "_Cached" in the filename. | General | Default: Unchecked |
| Enable 'still processing parameters' dialog| Warns if parameter processing from config files is incomplete when recording ends prematurely. | General | Default: Checked |
| Enable FTP Download | Enables offloading PGVs from FTP server as part of Ethernet Multi-Session Offload. | General | Default: Unchecked |
| Enable Logging CAN Data | Enables CAN data logging in live recordings. | General | Default: Unchecked |
| Enable Pre-build Configuration | Enables fast start by ignoring pre-cached PGVs. | General | Default: Unchecked |
| Low Disk Space Warning Threshold (MB) | Warns when free disk space drops within this threshold of the minimum disk space. | General | Default: 100MB |
| Minimum Disk Space (MB) | Minimum free disk space required during recording. Recording stops if below this value. | General | Default: 500MB (minimum allowed) |
| PGV exclusion list | Comma-separated list of PGVs to exclude from processing at start of recording. Same formats as DTV exclusion. | General | Default: Blank |
| PGV inclusion list | Comma-separated list of PGVs to include in processing at start of recording. Takes priority over exclusion list. | General | Default: Blank |
| PGV stand-alone list (HEX) | List of stand-alone PGVs in hexadecimal format. | General | Default: Blank |
| Polling Frequency to check available space (s)| How often to check available disk space. | General | Default: 5 seconds |
| Quad sources excluded from lap trigger | Streams (comma-separated) to exclude from lap trigger detection. | General | Default: Blank |
| Record only LIVE data | If checked, recording stops as soon as telemetry is uploaded. Requires "Enable Update Progress on clients" to be checked. | General | Default: Unchecked |
| Record telemetry data from start | If checked, session includes data from start of Data Server recording; otherwise, only from when ATLAS recording starts. | General | Default: Unchecked |
| Recording event script | Script executed on recording events (LIVE_STARTED, LIVE_STOPPED, OFFLOAD_STARTED, OFFLOAD_STOPPED). Format: 'script.exe EventId Argument'. | General | Default: Blank |
| Separate vTAG Session | Splits incoming DST recording with master and VTS data into two sessions. | General | Default: Unchecked |
| Temporary directory for recording files | Directory for temporary storage of session files during recording. If blank, files are written directly to data path. | General | Default: Blank |
| Unload unused PGVs on start recording | Removes PGVs from cache when recording starts. | General | Default: Unchecked |
| Virtual memory block size (KB) | Virtual memory slot size for memory mapping. | General | ATLAS: 5120KB, ADS: 1024KB |
| Warn When Config is Missing | Warns if logging config is missing for loaded session. | General | Default: Checked |
| Wideband minimum lap time | Minimum allowed time between lap triggers (>0s). | General | Default: 10 seconds |
| Live data feed retrieval path | Directory for storing intermediate LDR files when using LDF. | Live Data Feed | Default: `:\Users\\Documents\My Documents\McLaren Electronic Systems\ATLAS 9\LDS\` |
| PGV request timeout (s) | Max time to wait for requested PGV files via LDF. | Live Data Feed | Default: 30s |
| Log file folder | Directory for log files. | Logging | Default: `:\Users\\Documents\McLaren Electronic Systems\ATLAS 9\log` |
| Message log file size (MB) | Log file size limit; new file created when limit reached. 0MB = unlimited. | Logging | Default: 0MB |
| Message log level (for debugging) | Logging level for developer/debugging diagnostics. | Logging | Default: 'Not Logging' |
| Raw data logging | Saves raw data received during recording for telemetry diagnostics (.raw and .raw_tm files). | Logging | Default: Unchecked |
| Raw data root folder | Default folder for raw data logging files. In addition, if the session folder path in the recorder is not blank then it will also append that session folder name on to the default raw data root folder. e.g. Raw data root folder = C:\Server\Data and the recorder's Session folder is C:\Recorder then the path used will be C:\Server\Data\Recorder | Logging | Default: Blank |
| Sequence number anti-wrap time (hours) | Threshold for unwrapping sequence numbers if packet time is much earlier than latest. | Telemetry | Default: 0 (Disabled) |
| Telemetry guard filter length | Synchronisation length for telemetry guard. | Telemetry | Default: 10 |
| Telemetry guard time (s) | Rejects data if timestamp difference between packets exceeds this value. | Telemetry | Default: 0 seconds |
| Unit Comms Default Timeout (ms) | Default timeout for unit communications. | Telemetry | Default: 200ms |
| Ethernet buffer size (MB) | Local cache size for Direct Ethernet Wirelink. | Telemetry | Default: 5MB |
| Ethernet offload connection retries | Number of times to retry reconnecting during offload if connection lost. | Telemetry | Default: 10 |
| Ethernet receive timeout (ms) | Time to wait before retrying a receive message. | Telemetry | Default: 500ms |
| Ethernet retries | Number of times to retry a message before aborting and displaying a warning. | Telemetry | Default: 1 |
| Ethernet send timeout (ms) | Time to wait before retrying a send message. | Telemetry | Default: 500ms |
| Ethernet upload config unique response | Must match client-specific BIOS configurations. | Telemetry | Default: Unchecked |
| Ethernet upload message extended timeout (ms)| Time before Quad Ethernet Telemetry offload times out. | Telemetry | Default: 500ms |
| Ethernet upload message interval timeout (ms)| Time before Quad Ethernet Telemetry data is re-requested during upload. Auto-extends if data is received outside this timeout. | Telemetry | Default: 3ms |
| System Monitor base folder | Folder for System Monitor files. Multiple paths allowed (separated by semicolon). | System Monitor Folders | Editable |
| Logging configuration folder | Folder for logging configuration files (must be ATLAS\Config\Logging\AutoConfig). Multiple paths allowed. | System Monitor Folders | Editable |
| Car definitions file | Location and filename for car definitions, which define network communication for cars. | System Monitor Folders | Editable |
| Ancillary parameters folder | Folder for Logging Configurations created in System Monitor. Controls which parameters are logged and how. | System Monitor Folders | Editable |
| Parameter Unlock List folder | Folder where ATLAS searches for Parameter Unlock Lists. | System Monitor Folders | Editable |
| Custom PGV folder | Folder where ATLAS stores received PGV files. | System Monitor Folders | Editable |
| Configuration Folder | Folder for MAT.Atlas.TCPRecorder if using TCP listener recorder. | Folders | Editable |
| Default Data Path | Default path where sessions are stored unless overridden. | Folders | Editable |
| Decode DLLs (per stream) | Path to decode DLL for each of 16 streams (00–15) for processing generic data sources. Can browse or reset to default (AtlasApiDecoder64.dll). | Decode DLLs | Default: CustomDLLs\AtlasApiDecoder64.dll |
| Debug Decode DLL | Allows decode DLL to crash and generate a memory dump for debugging. | Decode DLLs | Checkbox |
| Stream Server Configurations | List of Stream Server configurations for the Stream Recorder. | Stream Recorder | Editable |
| Friendly Name | Name for the Stream Server configuration. | Stream Recorder | User-defined |
| Broker URL | URL and port of the broker for the Stream Server. | Stream Recorder | User-defined |
| Stream Port | Port of the Stream Server. | Stream Recorder | User-defined or default |
| Stream Creation Strategy | Strategy for stream creation in the broker: **TopicBased** (each stream is a topic) or **PartitionBased** (streams are partitions in one topic). Must match broker. | Stream Recorder | TopicBased or PartitionBased |
| Partition Mapping | Maps streams to partition numbers (only for PartitionBased strategy). Must match broker mapping. | Stream Recorder | User-defined |
---
# Workbooks
Workbooks in ATLAS define your workspace layout and the arrangement of elements on the screen. Every ATLAS session contains at least one Workbook, which can hold multiple Pages, and each Page can display several [Displays](../displays/index.md).

## Saving and Opening Workbooks
- **Save your workspace:** Workbooks are saved as `.wbkx` files, preserving the formatting, size, and position of each Display and Page.
- **Open existing workspaces:** Use the File menu to open a Workbook. This replaces your current workspace. If you have unsaved changes, ATLAS will prompt you before proceeding.
- **Save As:** To rename a Workbook, use the Save As command. The default name is assigned when first opened (e.g., Workbook1).
!!! note
Compare Sets, Session data, Bit Config Files, Functions files, Alarm Files, Circuit Display Definitions, SurfaceMap Display Definitions, and PCU Dash Display RAW CAN files are not stored in `.wbkx` files but are automatically opened by the Workbook. If these files are missing, Displays will be empty.
## Working with Pages
- **Default setup:** When ATLAS starts or a new Workbook is opened, it includes one Page.
- **Multiple Pages:** You can add, float, and arrange multiple Pages within a Workbook. Only one Page is selected at a time, but you can view several by floating them.
- **Page Bar:** Located at the top of the Main Window, it displays tabs for each Page. Use horizontal scroll arrows if tabs exceed available space.
### Page Management Options
Right-clicking a Page tab opens a menu with options to:
- **Set:** Switch or remove Compare Sets associated with the Page.
- **No Association:** Remove the current Compare Set link.
- **Lock to Current Association:** Lock the Page to its current Compare Set.
- **Title:** Edit the Page name.
- **Page Colour:** Underline the tab with a chosen colour.
- **New:** Add a new Page.
- **Paste/Import Display:** Add copied or saved Displays.
- **Duplicate:** Copy the Page and its Displays.
- **Export:** Save the Page for use in other Workbooks.
- **Close/Close Others/Close Tab Group:** Manage Page tabs.
- **Float/Float Page Group:** Move Pages into separate windows.
- **Pin Tab:** Toggle pin status.
- **New Horizontal/Vertical Tab Group:** Organize tabs in groups.

## Selecting Pages
- Click the desired tab on the Page Bar.
- Or, press **Page Up** or **Page Down**.
## Adding Pages
To add a new Page:
- Select **New** from the File menu, then **Page**.
- Click the **+** on the Page Bar.
- Click the **New Page** icon on the Main Toolbar.
- Right-click a Page tab and choose **New Page**.
- Press **Ctrl + Q**, then select **New Page**.
New Pages are named sequentially (e.g., Page2, Page3).
## Closing Pages
To close a Page:
- Click the **X** next to the Page name on the Page Bar.
- Or, right-click the Page Bar and select **Close**.
## Status Bar
The Status Bar appears at the bottom of the ATLAS Main Window and provides real-time feedback on system activity:
- **Last Action:** Displays a brief description of the most recent significant event, such as "Recording started" or error notifications.
- **Recorder Status:** Shows a symbol for each connected recorder, with initials indicating the recorder type. Status is highlighted by colour—yellow for idle, red for active recording.

- **Error Count:** Indicates the number of error messages. Click to view details; right-click and select **Clear** to remove the messages.
- **Alarms Warnings:** Shows the count of active alarms with warning status and lists the five most recent alarms. Refer to [Alarm Warnings](../alarms/index.md) for more information.

## Importing/Exporting Configuration
It's possible to export and import configurations, a useful action when you want to send your ATLAS workbook setup to another and ensure that everything is setup and immediately setup without repeated setup.
To export your configuration:
1. Go to `Tools > Import/Export Configuration`
2. Click `Refresh Current Configuration`
3. Select the source files you wish to include in the configuration export
4. Define a name for this profile configuration
!!! tip
Make sure the name is identifiable, as multiple profiles can be part of the same configuration bundle file.
5. Click `Export` to download your configuration bundle file.

To import a configuration:
1. Go to `Tools > Import/Export Configuration`
2. Click the `Import ATLAS 10 Configuration Bundle` tab
3. Browse for the `.acgx` configuration bundle file
4. Select from the profile you wish to import and the source files.
5. Click `Import` to begin

---
# Toolbar
Toolbars provide quick access to various ATLAS commands. By default, they are docked along the top edge of the Main Window.
Toolbar buttons are duplicates of Menu commands or other controls. Each item is described by its ToolTip text.
Any command that is unavailable in a given context is greyed out but remains on the toolbar.
Toolbars can be moved and rearranged by dragging the toolbar handle, found on the left-hand end of each toolbar:
| Action | Icon | Description | Toolbar |
|--------|------|-------------|---------|
| New Workbook |  | Create a brand‑new workbook. | Main Toolbar |
| Open Workbook |  | Open an existing workbook file. | Main Toolbar |
| Save Workbook |  | Save changes to the current workbook; prompts for a name if it hasn’t been saved before. | Main Toolbar |
| Save Workbook As |  | Save a copy of the current workbook under a different name. | Main Toolbar |
| Add New Page |  | Insert a new page into the active workbook. | Main Toolbar |
| Bar Display |  | Insert a Bar Display into the active workbook. | Display Toolbar |
| Bing Map Display |  | Add a Bing Map‑based display to the workbook. | Display Toolbar |
| Bit Display |  | Add a Bit Display for showing bit/boolean states. | Display Toolbar |
| Block Bar Display |  | Add a Block Bar Display for block‑style bar visuals. | Display Toolbar |
| Circuit Display |  | Add a circuit/track visualization display. | Display Toolbar |
| Countdown Timer Display |  | Add a display that counts down from a set time. | Display Toolbar |
| Error Display |  | Add a panel to show errors/alerts. | Display Toolbar |
| Events Display |  | Add a display that lists or plots events. | Display Toolbar |
| Histogram Display |  | Add a histogram to visualize distributions. | Display Toolbar |
| Loadmap Display |  | Add a load‑map style visualization. | Display Toolbar |
| Notepad Display |  | Add a simple notes/notepad panel. | Display Toolbar |
| Numeric Display |  | Add a numeric readout for key values. | Display Toolbar |
| PCU‑Dash Display |  | Add a PCU dashboard‑style display. | Display Toolbar |
| Scatterplot Display |  | Add a scatter plot visualization. | Display Toolbar |
| Summary Display |  | Add a summary panel aggregating key metrics. | Display Toolbar |
| Surface Map Display |  | Add a surface‑map view. | Display Toolbar |
| Video Display |  | Add a player panel for video content. | Display Toolbar |
| Waveform Display |  | Add a waveform/trace plot area. | Display Toolbar |
| Web Browser Display |  | Embed a web browser view inside the workbook. | Display Toolbar |
| Alarm Editor |  | Open the Alarm Editor tool. | Browser Toolbar |
| Session Browser |  | Open the Session Browser. | Browser Toolbar |
| Parameter Browser |  | Open the Parameter Browser. | Browser Toolbar |
| Function Editor |  | Launch the Function Editor. | Browser Toolbar |
| Value Cursor |  | Show a vertical cursor to read values at a chosen point. | Cursor Toolbar |
| Cross Hair Cursor |  | Show intersecting vertical and horizontal guides for precise value reads. | Cursor Toolbar |
| Gradient Cursor |  | Display a cursor that reports the gradient/slope at the selected point. | Cursor Toolbar |
| Hide Cursor |  | Turn off the cursor overlay on the display. | Cursor Toolbar |
| Create Zoom Box |  | Drag to zoom into a region on Waveform or Scatterplot displays. | Display View Toolbar |
| Undo All Zooms |  | Reset all zoom levels back to the default view. | Display View Toolbar |
| Auto‑scale |  | Automatically fit data to the available plotting area. | Display View Toolbar |
| Reset Auto‑scale |  | Exit auto‑scale and return to manual/normal scaling. | Display View Toolbar |
| Distribute Parameters |  | Arrange selected parameters in equally sized rows (Waveform). | Display View Toolbar |
| Reset Distribute Parameters |  | Revert to the standard parameter layout (Waveform). | Display View Toolbar |
| Toggle Display Title Bar |  | Show or hide the title bar for the selected display. | Display Titles Toolbar |
| Move to Previous Lap |  | Move the cursor back to the prior lap. | Laps Toolbar |
| Move to Current Lap |  | Zoom so only the currently selected lap is visible. | Laps Toolbar |
| Move to Next Lap |  | Advance the cursor to the next lap. | Laps Toolbar |
| Laps & Markers Editor |  | Open the editor to view or modify laps and markers in the primary session. | Laps Toolbar |
| Move to Next Signal Change |  | Navigate to the adjacent signal change (next). | Laps Toolbar |
| Move to Previous Signal Change |  | Navigate to the adjacent signal change (previous). | Laps Toolbar |
| Quick Access Assistant |  | Launch the assistant to quickly add parameters, functions, displays, or pages. | Quick Access Toolbar |
| Go To |  | Launch the Go To plugin to jump to a specific lap or marker in the primary session. | Go To Feature Toolbar |
| Refresh Calculated Parameters |  | Recompute all calculated parameters across the entire workbook. | Refresh Toolbar |
| Reset Parameter Properties |  | Resets the settings for all parameters to their default settings. | Refresh Toolbar |
---
# Overview
ATLAS provides powerful tools for visualising data over time using Timebases and Graphical Timelines. Each Display has a Timebase, defined by a start and end time (duration) and a current position. Timebases can be set independently or linked across Displays, and are updated automatically when telemetry is received.
The Graphical Timeline, shown at the top of the ATLAS Main Window, lets users control the Timebase using mouse interactions. It displays key session information, lap selection, markers, and navigation buttons for quickly moving between laps. The LapBar visually represents session duration, with laps and fastest lap highlighted.
For Compare Sets with multiple sessions, the Timeline offers options to compare whole sessions, single laps, or fastest laps, and allows setting time offsets between sessions.
This overview introduces the main concepts and controls for managing time and position in ATLAS, helping users navigate and analyse session data efficiently.

---
# Timebase and Timeline
Each Display in ATLAS has a **Timebase**, defined by:
- **Start and End Point**: The time range covered.
- **Duration**: The length of time shown.
- **Position**: A specific point within the Timebase.
**Default Settings**: Timebase duration and position are based on the absolute time in the active Session. Displays can have independent or linked Timebases—changes to a linked Timebase affect all associated Displays.
### Adjusting the Timebase
You can change the Timebase in several ways:
- **Position & Duration**:
- Use the Graphical Timeline
- Use Move controls
- **Position Only**:
- Move the cursor in Waveform, Circuit, or Scatterplot Displays
- **Duration Only**:
- Use Zoom controls in the Waveform Display
When telemetry is received, the Timebase position updates automatically.
## Timeline Overview
The **Timeline** is shown at the top of the ATLAS Main Window when a Session or Compare Set is loaded. It provides graphical control over the Timebase and lets you navigate, select laps, and compare data.

### Timeline Components
- **Set Tag**: Indicates which Session or Compare Set the Timeline applies to.
- **Set Name**: Shows driver and session description.
- **Lap Selection**: Select laps to change the Timebase.
- **Marker Selection**: Jump to specific points or ranges using markers.
- **Navigation Buttons**:
- Previous Lap
- Next Lap
- Fastest Lap
- **Lap Bar**: Visualizes session duration and lap boundaries.
- **Time Position**: Marked by a vertical red line.
- **Compare Set Scope & Offset**: Choose what to compare (whole session, single lap, fastest lap) and set time offsets between sessions.
## Timeline Actions
Interact with the Timeline using your mouse and keyboard:
- **Double-click a lap**: Selects the whole lap as Timebase, centers Time Position.
- **Triple-click**: Selects the entire session as Timebase.
- **Click + Drag**:
- Left to right: Select any duration
- Right to left: Select whole laps
- **Right-click**: Remove sessions or manage Compare Sets.
- **Left-click a Set tag/number**: Show/hide Compare Sets.
- **Right-click session identifier**: Promote to primary, delete, or view session details.
- **Zoom**: Use `+` and `-` keys or mouse wheel to zoom in/out on the Timeline.
## Timebase vs Distance Mode
The **Waveform Display** supports two modes:
- **Time Mode** (default): Parameters plotted against time.
- **Distance Mode**: Parameters plotted against distance.
**When to use each mode:**
- Use **Time Mode** for time-based analysis (e.g., event timing, telemetry trends).
- Use **Distance Mode** for lap comparison, performance over track segments, or when assessing lap time improvements.
### Switching to Distance Mode
1. Select a valid Distance parameter in `Tools > Options > General > X Axis Mapping`.
2. Add and configure the Distance parameter (e.g., `sLap`).
3. In the Waveform Display, press `K` to toggle modes, or right-click and select the mode from the context menu.
When Distance Mode is active, a Time Difference (TDiff) function is shown, helping you compare lap times and performance.

## Timeline Visibility
Timelines are visible if any display is associated with their Set. You can force visibility by right-clicking the Set marker and checking the Sets to always display. To show all Timelines, use `View > F1 Timeline > Show All Compare Sets`.

## Session Details Tooltip
Hover over the session identifier in the Timeline to see session details. Customize which properties are shown by right-clicking and selecting `Session Details`. You can select up to 5 properties (default limit, configurable).


---
# Go To
The **Go To** feature in ATLAS 10 allows users to quickly navigate to specific laps, markers, or exact positions (by time or distance) within a session. This feature streamlines data exploration and analysis, making it easier to locate and review key moments.
### How to Open the Go To Window
You can access the Go To window in any of the following ways:
- Click the Go To icon on the ATLAS toolbar.
- Select **View > Go to** from the Menu Bar.
- Use the keyboard shortcut **Ctrl + G**.
### Navigation Options
The Go To dialog provides three main navigation options, selectable via a drop-down list:
1. **Laps** – Jump to a specific lap in the session.
2. **Markers** – Move to a defined marker (point or range) within the session.
3. **Exact Setting** – Position the cursor at a precise time or distance.
#### 1. Go To Feature - [Laps](../handling-data/laps-markers/laps.md)
- The default option is **Laps**.
- Select a lap from the drop-down list and click **Apply** to move the cursor to that lap.
- **OK** applies the selection and closes the window; **Cancel** closes the window without changes.
- For live or replay sessions, playback will pause and jump to the selected lap.

#### 2. Go To Feature - [Markers](../handling-data/laps-markers/markers.md)
- Select **Marker** in the options drop-down to navigate to a session marker.
- Choose a marker from the list:
- **Range Marker**: Cursor moves to the center of the range and waveform zooms to the marker's time base.
- **Point Marker**: Cursor moves to the marker point without changing zoom.
- For live or replay sessions, playback will pause and jump to the selected marker.

#### 3. Go To Feature - Exact Setting
Use the **Exact Setting** option to move the cursor to a specific time or distance.
**Time Mode:**
- Definitions available:
- **Exact Time**: Enter a time value to move the cursor directly to that point.
- **Time from start of lap**: Enter a time offset from the start of a selected lap.
- **Time from end of lap**: Enter a time offset from the end of a selected lap.
- If the session spans multiple days, a **Day** drop-down appears for selecting the day.
- If the entered time is out of session range, an error dialog will prompt for a valid value.

**Distance Mode:**
- Definitions available:
- **Exact Value**: Enter a distance value to move the cursor directly to that point.
- **Value from start of lap**: Enter a distance offset from the start of a selected lap.
- **Value from end of lap**: Enter a distance offset from the end of a selected lap.
- If the entered distance is out of session range, an error dialog will prompt for a valid value.

---
# USB Recorder
This guide provides a step-by-step overview of how to use a USB Logger system to collect, transfer, and visualise sensor data efficiently. It covers setup on the vehicle, data offloading procedures, and how to import and decode the data in ATLAS. Designed for flexibility, the system supports a range of operational environments.
## Prerequisites
- Motion Applied USB Logger unit.
- ATLAS Version 11.4.4.349-W47 or later.
If you're interested in how Motion Applied can advance your data systems, contact [sales@motionapplied.com](mailto:sales@motionapplied.com).
## Setup
??? example "Prefer to watch a video demonstrating how to integrate the USB Logger with ATLAS?"
**1. Connect the Logger to the ECU**
- Use an Ethernet cable to connect the ECU to the USB Logger.
- If you need quick access to the USB for session offloading, set the `log_destination` in `logger_config.json` to `usb_loom`.
In this mode, the logger writes data through the loom to a USB stick placed in an easily accessible location for fast retrieval.
- *(Optional)* You can adjust other logger configurations by editing the `logger_config.json` file. Each field includes comments explaining its purpose and valid values.
!!! warning
You can change the logger’s IP address in the `logger_config.jsonc` file under the `ethernet_settings` section.
The Logger IP address must be in the **same range** as the ECU IP address.
**2. Configure Logging from the ECU**
- Open **System Monitor**, connect to the TAG unit (e.g. TAG-320, TAG-510, or TAG-700), and in the **Explorer** tab navigate to: `BIOS > Data Acquisition > Telemetry > TLM-Px`.
- Locate the parameter `TLMPxIPAddress` and set it to the logger’s IP address from the `logger_config.jsonc`.
!!! tip
While the parameter may appear as `NTAG320TLMPxIPAddress` on TAG-320 units, other models like TAG-510 or TAG-700 may use a slightly different prefix. To ensure compatibility, look for the `TLMPxIPAddress` field under the **Telemetry > TLM-Px** section in the BIOS tree. This structure is consistent across supported TAG units.
- In ATLAS, go to **Tools > Options > System Monitor Folders** and set up the folders containing the required ECU configuration files (e.g., PGVs).
!!! info
When the vehicle is powered on, the ECU will automatically begin logging data to the USB drive. Depending on session length, multiple `.bin` files may be generated.
**3. Swapping the USB**
- When the vehicle enters the pit, remove the used USB and insert a new one.
- The ECU will continue logging to the new USB without interruption.
**4. Insert the USB into a PC**
- Plug the USB into a PC using the adapter provided in the kit.
- Copy the `.bin` files to a local folder on your PC.
- After copying, you may delete the `.bin` files from the USB to prepare it for reuse.
!!! info
Even if you accidentally delete the `logger_config.jsonc` file from the USB, the logger will **continue recording** using the last configuration it stored locally.
When you plug the USB back into the logger it will **automatically restore the latest version** of `logger_config.jsonc` onto the USB. You can then **review or update the configuration** as needed.
**5. Add a USB Logger Recorder in ATLAS**
- Launch **ATLAS**.
- Open the **Session Browser** (`CTRL + L`) and create a new recorder.
{: style="width:75%;"}
Set the following:
- **Database engine** (where the data will be stored)
- **Auto Export SSN2** *(optional)* to automatically export the created sessions to SSN2 once processing is complete.
Go to the USB Logger Bin File(s) tab and set:
- **Folder path** to the `.bin` file(s)
- **Select the bin files** you wish to import.
ATLAS will automatically detect and import multiple `.bin` files found in the folder as separate sessions.
!!! note
When specifying the folder path, ensure that all required `bin` files are located directly within that directory. ATLAS will not process files located in subfolders.
**6. Start the Recorder**
- The recorder will process each binary file individually, creating a new session per `bin` file. If *Auto Export SSN2* was selected when configuring the recorder it will export the converted `.ssn` files to the export folder after processing is finished.
- You can monitor progress via the status bar located in the bottom-right corner of ATLAS or in the recorder itself.
{: style="width:75%;"}
!!! warning
The USB Logger Recorder does not record in the same way as other recorders. Behind the scenes it replays existing data and generates a historical session file from the replay.
As a result you cannot drag the USB Logger recorder into a Set until it has finished converting the data. This recorder is **not** used for real-time replay.
**7. Using the Data**
- Once the session is fully read and marked as **Historical**, it will appear in the **Sources** panel.
- You can import the session into a **Set** using **Append** or **Compare** mode, like any other historical data.
{: style="width:75%;"}
Depending on the selected database engine:
- **SQLite**: Share the exported `.ssn` file via a network drive.
- **SQL Race**: Team members with access to the database can view the session directly.
## Use Cases
The USB Logger system is designed for flexibility and ease of use across a wide range of environments and industries. Example applications include:
**Extreme Environments**
Water-resistant design allows use in harsh weather or rugged terrain.
**Limited Storage**
Ideal for systems where the ECU has limited onboard storage capacity.
**Endurance Operations**
Supports long-duration sessions where quick data offloading is essential.
**Difficult Access**
Enables data retrieval without needing direct physical access to the ECU.
**Limited Telemetry Bandwidth**
Provides a fast alternative to telemetry for transferring session data.
**Scalable for Small Teams**
Runs directly on an engineer’s PC without requiring advanced setup. Can be integrated into larger systems later using tools like the SQL Race API.
---
# NASCAR Telemetry Recorder
ATLAS can be used for receiving and visualising Telemetric data from NASCAR’s Event Racing Data Platform. It is designed to connect to the data feed delivered live via JSON messages published from NATS.io message broker. The integration provides complete ATLAS data analysis functionality for use with the data from NASCAR. ATLAS currently supports all of the information collected to the CAN bus from Motion Applied’s TAG-400N.
## Prerequisites
* Access to live NATS data feed from NASCAR. Request Subscriber Access from NASCAR by emailing [data.engineering@nascar.com](mailto:data.engineering@nascar.com)
* ATLAS v11.3.1.540 or higher, which can be downloaded via our Motion Applied Portal [https://portal.motionapplied.com/](https://portal.motionapplied.com/)
* ATLAS Licence with NASCAR Telemetry Recorder add-on. Please contact [sales@motionapplied.com](mailto:sales@motionapplied.com)
## Setup
Once ATLAS has been installed and licensed:
**Configure NASCAR Server connections**
* Open ATLAS and click Tools | Options | Recorders | NASCAR Telemetry Recorder
* Edit and configure Integration (Replay), Trackside and Cloud NASCAR Server connections

!!! note
* You will receive two sets of credentials from NASCAR:
* Production - add these to your Trackside and Cloud server connection settings
* Integration - add these to your Integration (Replay) server connection settings
* Update the credentials / ca-file / cert-file / key-file paths so that they point to the subscriber credentials from NASCAR

* Click OK on the NASCAR Server connection
**Configure Wideband minimum lap time**
* In the Recording option (Tools | Options | Recorders | Recording | General) set Wideband minimum lap time (secs) = **1** second

* Click OK to save and close the Options screen
**Add a NASCAR Telemetry Recorder**
* In Session Browser, add a NASCAR Telemetry Recorder

* Configure the NTR Recorder Editor dialog

!!! info
* Recorder Name - can be any friendly name e.g. Car 6
* Server:
* Trackside - for use at track (recommended hard-wired)
> Wi-Fi can be very spotty; if data has dropouts, then wired connection will be necessary. Dropouts have not been seen in remote recordings of data.
* Cloud - for use at factory or other non-track locations
* Integration (Replay) - for use after event, replays constant stream of data for testing purposes
* File Telemetry - for replaying JSON files from previous events. These can be then be saved to an SSNDB or as SSN2 files.
* Session Identifier - name of the session can be configured using tokens and information from the data, e.g. $SeriesId$_$RunType$_$RaceId$_$VehicleId$_%y%m%d%H%M%S
* Car Number - Select a vehicle ID to get the relevant data for that car
* Database engine - Select SQLite for storing data in a local cache. SQLServer option can be selected if there is a SQL Race database set up.
* Database path - If SQLite option is selected, user can set a local path, folder and name the .ssndb for the local cache. For SQLServer option, a connection string for the database will be needed.
> Do not use a folder location which is being used to sync the content of the folder to OneDrive. This doesn't work well with the Recorders as ATLAS has to constantly write and read from this location.
* Auto Export SSN2 - If you check this box an SSN2 export for every recording will be saved such that it creates a file per start/stop of the recorder.
* Select Close and add the recorder to a SET, then click start. If the NATS server is streaming data, the NTR recorder box will begin to flash red if a connection is achieved. If parameters are not present it is possible the car is not streaming.
> If the recorder is not working, this might be down to a Firewall issue, so please check with your IT department
!!! note
* You can also access the previously recorded JSON files from [https://teamcontent.nascar.com/](https://teamcontent.nascar.com/) These file can be downloaded and played back into ATLAS and recorded as SSN2 files.
> The JSON files must be copied into: C:\NASCAR\race_data
## Hints and Tips
!!! tip
* ATLAS performance is dependent on the hardware it is being run on and scales based on the processors and RAM available to the ATLAS application. We recommend using i7 or higher processor for running multiple recorders i.e. for streaming data from multiple cars.
* Queue Size - we have included a diagnostic parameter called Queue Size, which tells how many packets are in the queue still to be processed. Low number (10's) denotes that the application is keeping up with the live stream, if not please check the recommended hardware requirements for ATLAS.
* Numeric Displays and some parameters will need parameter Display Min and Max set. By default, they are way out of range and will load in very tiny text. Max 100 and Min 0 is a good starting point.
* The provided Workbook has a Diagnostic Bit display. The APPStatus and BIOSStatus appear to be correct in the messages sent from server. The NLEDFlashFaults appear to be wrong, and NASCAR is aware.
* Alarms and Functions will work with NTR data, but ATLAS cannot handle parameter names with spaces. So “Engine Speed” will not work in a function or alarm. NASCAR is aware of this, and we will investigate either getting the parameter names changed or updating ATLAS to accept name spacing.
* All sessions by default will record into a SQLite database on your hard drive and export to SSN2 if you choose. SRMS (SQL Race Management Studio) can be used to edit or delete sessions from your SQLite databases after a weekend if they are not required. Please contact an FAE for further guidance on using SRMS.
## Known Limitations
!!! warning
* Data stream is UTC time and at 23:59.59 (7pm EST) ATLAS will stop recording. Restarting recorders will be necessary. This is known and our ATLAS team is looking at this.
* Recorders - There is a known issue with ATLAS Telemetry Recorders (NTR included). If a recorder is added to a set and then removed, the recorder will disappear when ATLAS is restarted. This can be very inconvenient, so we recommend assigning a recorder to a set and leaving it. You can have up to 20 sets in a workbook and probably won’t have more than 20 recorders running at once.
---
# Data Server Telemetry Recorder
## Purpose
Connects to a live telemetry stream from an ATLAS Data Server over a network.
## Prerequisites
1. ATLAS Data Server must be running on the source machine.
2. The TAG channel must match between client and server.
3. The ATLAS client must be on the same network or have access to the server.
## Setup Instructions
1. Open Session Browser in ATLAS.
2. Add a Data Server Telemetry Recorder.
3. Configure the following:
- Recorder Name: Friendly name for identification.
- Data Server: Select from {servername}:{Data Stream name}.
- Refresh: Click to update the list of available servers.
- Session Identifier: Use tokens or manual entry.
- Auto Record: Enable if you want recording to start automatically.
4. Click Start to begin manual recording.
## Notes
The first client to connect sets the TAG channel.
If the server list is outdated, click Refresh or restart ATLAS.
Recording will not start unless the Data Server is running and the TAG channel matches
---
# File Telemetry Recorder
## Purpose
Replays previously recorded raw telemetry data for diagnostics or analysis.
## Setup Instructions
!!! note
.raw_tm file must exist. These are created during sessions where raw data logging is enabled.
1. Open Session Browser.
2. Add a File Telemetry Recorder.
3. Configure:
- Recorder Name
- Telemetry Timestamp File: Browse to .raw_tm file.
- Session Identifier
4. Click Start to begin playback.
## Notes
Useful for debugging or training without needing live data.
The file must be located in the same directory as the session and named accordingly
---
# Ethernet File Telemetry
## Purpose
Streams live data from ECUs connected via Ethernet (e.g. TAG-310).
## Prerequisites
Car Definition must be loaded.
ECU must be connected via Ethernet.
## Setup Instructions
1. Open Session Browser.
2. Add an Ethernet Telemetry Recorder.
3. Configure:
- Recorder Name
- Car: Select from Car Definitions.
- Unit: Choose a specific unit or “All Units”.
- Data Versions: Enable to upload DTVs at start.
- Events / Row Data: Enable to save .evt and .row files.
- Export Config as Text
- Session Identifier
4. Click Start to begin recording.
## Notes
Ideal for continuous data streaming during track sessions.
Does not require a radio link—Ethernet is sufficient
---
# Ethernet Multi Session Offload
## Purpose
Offloads multiple stored sessions from ECUs that support multi-session memory (e.g. TAG-310).
## Prerequisites
ECU must support multi-session (BIOS B023+).
ATLAS or ADS must be running.
## Setup Instructions
1. Open Session Browser.
2. Add an Ethernet Multi-Session Offload Recorder.
3. Use the Connection Tab to:
- Select Car and Unit.
- Choose SQL Server or SQLite.
- Set Export Folder.
- Define Session Identifier.
- Use the Select Sessions Tab to:
- View sessions stored on the ECU.
- Select sessions to offload.
- Use buttons: Select All, Clear All, Hide Offloaded, Query.
4. Click Start to offload selected sessions.
## Notes
Sessions with overlapping timestamps are grouped into one SQL Race session.
If the unit doesn’t support multi-session, use the standard Ethernet Telemetry Recorder
---
# Ethernet Offload
## Purpose
Offloads the most recent session from an Ethernet-connected ECU.
## Prerequisites
ECU must be connected and powered.
Car Definition must be loaded.
## Setup Instructions
1. Open Session Browser.
2. Add an Ethernet Offload Recorder.
3. Configure:
- Recorder Name
- Car / Unit
- Data Versions
- Export Config as Text / M Files
- SQL Race Database Type
- Export Folder
- Session Identifier / Details
4. Click Start to begin offload.
## Notes
Only the most recent session is offloaded.
Ideal for quick post-session data capture
---
# Stream Recorder
## Purpose
Connects to a Kafka broker to record live telemetry via the [Open Data Streaming Architecture](https://docs.atlas.motionapplied.com/developer-resources/secu4/docs/).
## Prerequisites
Stream Server Configuration must be set up in Tools|Options|Recorders|Stream Recorder.
## Stream Server Configuration
Before any recording can be done, the Stream Server Configuration must be set. This tells the Stream Recorder important things about the Kafka broker it is recording from.

# First time Setup
1. Click on Tools|Options|Recorders|Stream Recorder
2. Click on Add to create new Stream Server Configuration.
3. Configure (Basic Settings):
- **Friendly Name** - The name at which the configuration will be referred to (This should be unique).
- **Broker URL** - The URL of the Kafka Broker.
- **Domain Name** - The Domain Name of the Stream API which was setup for the broker. This is only needed if the Producer's Stream API has a domain name defined.
- **Stream Creation Strategy** - The strategy at which new streams are made in Kafka. This needs to match the producer's Stream API settings. There are two modes:
- **Topic Based** - Streams are divided into Kafka Topics.
- **Partition Based** - Streams are divided into Partitions in a single Kafka topic.
- **Partition Mapping** - Only required if Partition based Stream Creation Strategy was selected. Maps which stream goes to which parition number. This needs to match the producer's Stream API settings.
4. Click OK and the Stream Server Configuration is now available for all Stream Recorders in that ATLAS to use.
# Advanced Settings (Available on ATLAS versions 11.5.2.972-W28 and later)
There are Advanced Settings available for the Stream Server Configuration. This is used to setup Kafka Security and enable Kafka Tuning.
## Kafka Security
Kafka Security is only needed if Kafka is setup with security enabled.
For more info, look at [Kafka Security](https://docs.atlas.motionapplied.com/developer-resources/secu4/stream_api/reference_docs/configuration/kafka-security/#overview).
## Kafka Tuning
Kafka Tuning is available to fine tune how Stream Recorder consumes from Kafka. The file path are for the Kafka Tuning json. For more info, click [Kafka Tuning](https://docs.atlas.motionapplied.com/developer-resources/secu4/stream_api/reference_docs/configuration/kafka-broker-tuning/).
## Recording Modes
The Stream Recorder supports two operational modes for consuming OSAP data from Kafka. These modes determine where in the stream the Recorder begins reading data and how it handles historical backlog.
1. **Live Mode:** Live mode begins consuming data only from the moment the Recorder starts. The Recorder attaches to the Kafka topic at the current offset and continues forward.
2. **Live with Catchup Mode:** The Recorder starts at the live edge, ensuring it processes new data immediately. Simultaneously, it begins consuming all data from the start of the session. Catch‑up happens in the background, at a controlled rate, without disrupting live processing. Priority is always given to leading‑edge, real‑time data.
## Group Id
The group id allows Stream Recorder to set the Kafka Consumer Group ID. This allows Stream Recorder to track the current offset in Kafka and continue reading from the last offset it read from. So if the ATLAS client disconnects and rejoins the stream, it will continue from the last offset it read from (assuming the topics has not been cleared down of messages). If left blank, Stream Recorder will always read from the leading edge of the session.
## Setup Instructions
1. Open Session Browser.
2. Add a Stream Recorder.
3. Configure:
- **Recorder Name**
- **Database Engine:** SQLite or SQL Race.
- **Database Path** / **Connection String**.
- **Delete Recorded Session on Close**
- **Auto Export to SSN2** (If recording to SQLite)
- **Export Folder**
- **Stream Server** / **Data Source**
- **Session Identifier Pattern** / **Source**
- **Recording Mode**
- **Group Id**
- **Session Details Source** / **Details**
4. Choose between:
- **Start:** Waits for a live session and records it.
- **Auto Record:** Continuously records new sessions as they appear.

---
# Overview
## What is a Session?
A Session in ATLAS is a structured collection of data samples recorded from a vehicle. These samples are captured by a data logger and uploaded to ATLAS either:
Live, via telemetry (wireless transmission), or
Offline, via a wirelink (physical connection).
Each Session is automatically created and stored in an SQL Race database as it is recorded. This database replaces the older .ssn file format used in previous versions of ATLAS. However, legacy .ssn files can still be loaded for analysis and comparison.
## Types of Sessions
There are two primary types of Sessions in ATLAS:
**Historical Sessions**
These are Sessions that have already been recorded and stored. They can be loaded at any time for review and analysis.
**Telemetry Sessions**
These are live Sessions that are displayed in real-time as data is received from the vehicle.
!!! warning
Data visualisation and analysis in ATLAS can only begin once a Session is loaded into a Workbook. A Workbook is the environment where data is displayed using graphs, tables, and other visual tools.
## Why Sessions Matter
Sessions are the foundation of all data analysis in ATLAS. They allow engineers and analysts to:
- Monitor vehicle performance in real time
- Compare data across different runs or configurations
- Identify trends, anomalies, or failures
- Share insights with other team members
Sessions can be combined, compared, and manipulated in various ways to support these goals. The tools used to manage Sessions include:
- Session Browser: The main interface for loading, recording, and editing Sessions.
- Composite Sessions: Merged Sessions that combine multiple data recordings into one.
- Compare Sets: Groups of Sessions loaded together for side-by-side analysis.
### Key Concepts
| Term | Definition |
|-------------------|----------------------------------------------------------------------------|
| Session | A dataset recorded from a vehicle, stored in an SQL Race database. |
| Historical Session | A previously recorded Session. |
| Telemetry Session | A live Session streamed in real time. |
| Workbook | The environment in ATLAS where Sessions are visualised and analysed. |
| Session Browser | The tool used to manage Sessions. |
| Composite Session | A combination of multiple Sessions treated as one. |
| Compare Set | A group of Sessions loaded together for comparison. |
---
# Session Browser
## Purpose of the Session Browser
The Session Browser is the primary interface in ATLAS for managing telemetry data Sessions. It allows users to:
- Load previously recorded (Historical) Sessions
- Record new (Live) Sessions
- Configure and manage data Recorders
- Combine multiple Sessions into Composite Sessions
- Group Sessions into Compare Sets for analysis
- View and edit Session metadata
- Connect to various data sources (e.g. databases, folders, services)
This tool is essential for any user working with telemetry data in ATLAS, whether for real-time monitoring or post-session analysis.
## How to Open the Session Browser
You can open the Session Browser in one of the following ways:
**Toolbar Icon**
Click the Session Browser icon on the ATLAS toolbar.
**Menu Bar**
Navigate to `View > Session Browser`.
**Keyboard Shortcut**
Press `Ctrl + L` on your keyboard.
Once opened, the Session Browser will appear within the ATLAS interface.
## Layout of the Session Browser
The Session Browser is divided into six main panels, each serving a specific function:

### 1. Session Sources
This panel allows you to define where ATLAS should look for Sessions. Supported sources include:
- Folders on your local machine or network
- SQL Race databases
- RTA service connections (requires an RTA licence)
To add a new source:
1. Click the Add Data Source button or right-click the Sources panel.
2. Choose one of the following:
- Connection Manager: For SQL Race databases
- Folder Manager: For local or network folders
- Service Connection Manager: For RTA hosts
Once added, ATLAS will index the source and display available Sessions in the Session List.
### 2. Session Filters
Filters help you narrow down the Sessions displayed in the Session List. By default, filters include:
- Circuit
- Driver
- Run Type
You can customise filters by:
1. Right-clicking the Filters title to see all available categories
2. Selecting or deselecting filter options
3. Saving filter combinations as Favourites for quick reuse
### 3. Session Recorders
This panel is used to configure and manage data Recorders for capturing live telemetry. Supported Recorder types include:
- Data Server Telemetry
- Ethernet Telemetry
- File Telemetry
- Ethernet Multi-session Offload Data Recorder
- TCP Listener Recorder
- NASCAR Recorder (requires NASCAR licence)
**Recorder Modes**
When adding a Recorder to a Set, you can define its behaviour:
- Create: Each new recording creates a new Session.
- Replace: Each new recording replaces the previous Session in the Set.
- Append: New recordings are appended to existing Sessions, forming a Composite Session.
!!! note
Starting a Recorder does not automatically load the Session into a Set. You must manually add it using the Session List or drag the Recorder into a Set.
### 4. Session List
This panel displays all Sessions available from the selected source. Each entry includes metadata such as:
- Session type (Historical or Live)
- State
- Driver
- Circuit
- Number of laps
You can:
- Search for Sessions using the search box
- Right-click to add Sessions to new or existing Sets
- Drag Sessions into Sets or onto other Sessions to create Composite Sessions
- Select multiple Sessions using `Shift + Click` or `Ctrl + Click`
### 5. Compare Sets List
Also known as the Set List, this panel shows which Sessions and Recorders are currently loaded into each Set.
Features include:
- Viewing Sessions within each Set
- Expanding Composite Sessions to see individual components
- Removing Sessions from Sets
- Customising columns (changes apply to both this panel and the Session List)
The active Set is highlighted with a coloured outline.
### 6. [Session Properties](properties.md)
This panel displays detailed metadata for the selected Session. Properties are colour-coded:
- White fields: Editable
- Grey fields: Read-only
Editable properties include:
- Session Name and Number
- Driver, Car, Engine, Circuit
- Weather, Notes, and other descriptive fields
- Lap Trigger Offset (used to align data across Sessions)
---
# Loading Sessions
## [What is a Recorder?](../recorders/usb-logger.md)
A Recorder in ATLAS is a tool that captures live telemetry data from a vehicle and stores it in an SQL Race database. Recorders are configured and managed through the Session Browser.
Supported Recorder Types
You can choose from several Recorder types depending on your data acquisition setup:
- Data Server Telemetry
- Ethernet Telemetry
- File Telemetry
- Ethernet Multi-session Offload Data Recorder
- TCP Listener Recorder
- NASCAR Recorder (requires a NASCAR licence)
Each type corresponds to a specific method of receiving telemetry data.
### Adding and Configuring a Recorder
1. Open the Session Browser.
2. Click the Add Recorder button.
3. Select the appropriate Recorder type.
4. Configure the Recorder settings as required.
Once added, the Recorder appears in the Recorders panel.
### Starting a Recording
To begin recording Click Start on the Recorder.
- Depending on the Recorder type, data may begin streaming immediately or wait for a trigger.
!!! note
Starting a Recorder does not automatically load the Session into a Set. You must manually add the Session to a Set to view and analyse it.
When a Recorder is added to a Set, you must define its mode. This determines how new recordings are handled in relation to existing Sessions.

**Mode: Create**
*Function:* Each new recording creates a new, separate Session.
*Behaviour:* Previously recorded Sessions remain in the Set as Historical Sessions.
*Use Case:* Ideal for capturing multiple independent runs or tests.
**Mode: Replace**
*Function:* Each new recording replaces the previous Session in the Set.
*Behaviour:* Only the most recent Session is retained.
*Use Case:* Useful for iterative testing where only the latest data is relevant.
**Mode: Append**
*Function:* Each new recording is appended to the existing Sessions in the Set.
*Behaviour:* Multiple recordings are merged into a single Composite Session.
*Use Case:* Best for continuous data collection across multiple runs or phases.
Composite Sessions created via Append mode are displayed as a single timeline in ATLAS. Green line separators indicate where individual Sessions have been joined.
## What is a Historical Session?
A Historical Session is a previously recorded Session stored in the SQL Race database. These Sessions can be loaded into ATLAS for review, comparison, or further analysis.
Loading Methods
You can load Sessions into a Set using the Session List in the Session Browser:
1. Double-click a Session to add it to the currently selected Set.
2. Drag and drop a Session into a Set.
3. Right-click a Session and choose:
- Add to New Set: Creates a new Set and adds the Session.
- Add to Set: Adds the Session to an existing Set.
4. Drag one Session onto another in the Set list to create a Composite Session.
5. Select multiple Sessions using Shift or `Ctrl + Click`, then:
- Right-click and choose Append and Add to New Set.
- Right-click and choose Append and Add to Set.
## What is a Compare Set?
A Compare Set is a group of one or more Sessions (or Composite Sessions) loaded together for side-by-side analysis. Compare Sets are essential for:
- Comparing different runs or configurations
- Analysing performance trends
- Identifying anomalies or inconsistencies

You can create a Compare Set in several ways:
1. Double-click a Session in the Session List.
2. Drag and drop a Session into the Sets panel.
3. Right-click a Session and select Add to New Compare Set.
4. Select multiple Sessions and:
- Right-click and choose Add to New Compare Set.
- Drag them into the Sets panel.
Adding to an Existing Compare Set:
1. Drag a Session onto an existing Set in the Sets panel.
2. Select multiple Sessions and drag them onto an existing Set.
### Viewing and Managing Compare Sets
The Compare Sets List (also called the Set List) shows all active Sets.
1. Click a Set tab to expand and view its Sessions.
2. Click the arrow next to a Composite Session to view its components.
3. Right-click a Session to remove it from the Set or press Delete.
Customising the Compare Sets View
1. Right-click column headers to add or remove metadata fields.
2. Changes apply to both the Compare Sets List and the Session List.
## What is a Composite Session?
A Composite Session (also known as an Appended Session) is a single Session formed by appending multiple Sessions together. This is useful for:
- Continuous data collection across multiple runs
- Reducing clutter by merging related Sessions
- Aligning data for comparative analysis

Creating Composite Sessions
- Historical Data: Load a Session into a Set, then drag additional Sessions onto it.
- Live Data: Use a Recorder in Append mode. Each new recording is automatically appended to the previous one.
Composite Sessions appear as a single timeline in ATLAS, with green separators marking the boundaries between original Sessions.

---
# Importing CSV and TXT Files
## Prerequisites
- Your licence must include **CSV/ASCII Import**.
- The source file must use a supported extension, such as `csv` or `txt`.
- The file must be in a delimited text format that ATLAS can describe with the available settings.
## Configure a CSV or TXT format
Open the ATLAS configuration/settings area and go to:
**General > Text Session Format**
This page maintains the text-file definitions, which is saved to:
`%LOCALAPPDATA%\McLaren Applied Technologies\ATLAS 10\SQL Race\DataProviders.xml`
### Add a new file type
1. Click **New**.
2. Enter the file extension **without the leading dot**.
Example: use `csv`, not `.csv`.
3. Fill in the format details for that file type.
4. Click **Set Definition** to save the definition.
ATLAS only allows one definition per extension, so `csv` and `CSV` are treated as the same extension.
## Meaning of each format field
| Field | Meaning |
| --- | --- |
| **Extension** | File extension to match, for example `csv` or `txt`. |
| **Total Header Lines** | Total number of non-data lines at the top of the file. |
| **Parameter Line** | Line number containing parameter/channel names. |
| **Group Line** | Line number containing group names. Use `0` if the file does not have one. |
| **Date Exists** | Whether the file includes date information. |
| **Time Format** | One of `DateTime`, `Milliseconds`, `Seconds`, or `Time`. |
| **Delimiter** | One of `Tab`, `Space`, `Comma`, or `Semicolon`. |
| **Unit** | Line number containing units. Use `0` if units are not present. |
| **Lap Marker** | Marker text used for lap markers in the file. |
## Load the file in ATLAS
After the format definition is in place:
1. Open **Session Browser**.
2. Switch to the **Files** tab.
3. Navigate to the folder that contains the CSV or TXT file.
4. Double-click the file/session name to load it.
If you use the same location frequently, you can add the folder to indexed sources or shortcuts from the **Files** tab context menu.
## Typical example
For a comma-separated file with two header rows:
| Field | Example value |
| --- | --- |
| Extension | `csv` |
| Total Header Lines | `2` |
| Parameter Line | `1` |
| Group Line | `0` |
| Date Exists | `True` or `False`, depending on the file |
| Time Format | `Milliseconds` |
| Delimiter | `Comma` |
| Unit | `2` if units are on the second header row, otherwise `0` |
| Lap Marker | `%` or whatever marker your file uses |
??? question "Troubleshooting"
**The file does not appear or does not load**
1. **Is the licence correct?** Confirm that **CSV/ASCII Import** is included in your licence.
2. **Does the extension match?** The file extension must exactly match a definition in **Text Session Format**.
3. **Was the dot omitted?** The extension must be entered without a leading dot — `csv`, not `.csv`.
4. **Are you in the right tab?** The folder must be opened from **Session Browser > Files**.
---
**Channels, units, or groups are wrong**
1. **Are the header line numbers correct?** Re-check **Total Header Lines**, **Parameter Line**, and **Group Line**.
2. **Is the delimiter right?** Confirm the delimiter matches the one used in your file.
3. **Is the time format right?** Confirm the chosen **Time Format** matches the data.
4. **Are optional lines set to zero?** Use `0` for any header line that does not exist in the file.
---
**Save fails in Text Session Format**
Each extension can only have one definition. Remove or rename any duplicate entries in the list before saving.
---
# Changing Properties
The Session Properties Panel in ATLAS provides detailed metadata for each Session. This information is essential for identifying, organising, and aligning Sessions for analysis. Some properties are editable, allowing users to customise or correct Session details, while others are read-only and automatically populated by the system.
## Session Identifier Macros
Session Identifiers (aka _names_) help you identify recorded sessions.
ATLAS provides formatting macros to fill in parts of the identifier automatically.
You can include them in the identifier when configuring a recorder.
!!! tip
These macros can also be used in Session Details (metadata).
### Time Codes
These codes format the session identifier from the time of recording:
| Macro | Description
| ------ | -------------------------------------------- |
| `%y` | Year (Short form - 2 digits: 00 to 99) |
| `%Y` | Year (Long form - 4 digits: 0000 to 9999) |
| `%m` | Month (2 digits: 01 to 12) |
| `%d` | Day of month (2 digits: 01 to 31) |
| `%H` | Hour (2 digits: 00 to 23) |
| `%M` | Minute (2 digits: 00 to 59) |
| `%S` | Second (2 digits: 00 to 59) |
!!! example
`%y%m%d%H%M%S` = `210730140617` _at 2021-07-30 14:06:17 local time_
### Session Details
These codes incorporate standard session details (metadata):
| Macro | Session Detail
| ------ | -------------------------------------------- |
| `%a` | _Car_ |
| `%c` | _Circuit_ |
| `%e` | _Engine_ |
| `%r` | _Driver_ |
| `%n` | _Session Number_ |
| `%t` | _Race/Test_ |
| `%O` | _Unit Data Source_ (populated automatically) |
### Parameter Data
To extract parameter values, use `${param}$`, where `{param}` is the parameter identifier or name.
This is commonly used together with text conversions — to spell out driver initials, for example.
!!! example
`$NDriverInitial1$$NDriverInitial2$$NDriverInitial3$_$NFOMRacingNo$` = `HAM_44`
If the parameter is not present — for example, while configuration is being processed — the macro will not be expanded.
## Accessing the Session Properties Panel
To view or edit Session properties:
1. Open the Session Browser.
2. Select a Session from the Session List.
The Session Properties Panel will appear, displaying all available metadata for the selected Session.
!!! tip
Editable fields are shown in white. Read-only fields are shown in grey.
## Editable Session Properties
These fields can be modified directly in the Session Properties Panel. Click on the value to edit it.
**Property**|**Description**
:-----:|:-----:
Session Name|The name assigned to the Session. Automatically generated but can be renamed for clarity.
Session Number|A numeric identifier. If the name ends in a number, it is incremented with each new recording. A blank entry is not incremented. Default is 1.
Pit Lane Trigger|Defines the position of the pit lane trigger relative to the team pit box. Options: None, After Pit, Before Pit.
Session Description|Free text field for describing the Session’s purpose or context.
Driver|Name of the driver for the Session.
Car|Identifier or name of the car used.
Engine Description|Description of the engine configuration.
Circuit|Name of the circuit or track.
Race/Test|Indicates whether the Session was part of a race or a test.
Chassis Number|Identifier for the chassis used.
Note 1 / Note 2 / Extra Notes|Free text fields for additional comments or observations.
Weather|Description of weather conditions during the Session.
Version|Optional versioning field for tracking changes or configurations.
Lap Trigger Offset|Distance (in metres) from the lap trigger to the Start/Finish line. Negative values = Start/Finish is ahead of the trigger. Positive values = behind. Used to align data across Sessions with different trigger positions.
!!! tip
Use consistent naming conventions and metadata values to make filtering and comparison easier across large datasets.
## Read-Only Session Properties
These fields are automatically populated by ATLAS and cannot be edited.
**Property**|**Description**
:-----:|:-----:
Unit Data Source|The Recorder that captured the Session data.
Date of Recording|The date and time the Session was recorded.
ECU Version|Version of the ECU (Engine Control Unit) used.
ECU Serial Number|Serial number of the ECU.
These values are critical for traceability and technical validation, especially when comparing Sessions across different hardware or configurations.
**Special Field: Pit Lane Trigger**
The Pit Lane Trigger setting affects how ATLAS calculates lap times and identifies the fastest lap. Options include:
- None: Trigger is located at the team pit box.
- After Pit: Trigger is after the pit lane. The last full lap may be the fastest and is included in analysis.
- Before Pit: Trigger is before the pit lane. The in-lap is excluded from fastest lap calculations.
This setting ensures accurate lap timing and should be configured based on the physical layout of the circuit.
**Special Field: Lap Trigger Offset**
The Lap Trigger Offset is used to align Sessions recorded with different lap trigger positions. It defines a consistent reference point on the track.
- Negative values: Start/Finish line is ahead of the trigger.
- Positive values: Start/Finish line is behind the trigger.
This is especially useful when comparing data from multiple Sessions recorded at the same circuit but with different trigger setups.
!!! note
The reference point does not have to be the Start/Finish line. Any consistent track feature can be used, as long as it is applied uniformly across Sessions.
## Best Practices
1. Always review and update Session metadata after recording to ensure accuracy.
2. Use descriptive names and notes to make Sessions easier to identify later.
3. Align Sessions using Lap Trigger Offset when comparing data across different setups.
4. Use consistent values for fields like Driver, Circuit, and Car to improve filtering and searchability.
---
# Database Connection Manager
## Database Connection Manager
This guide explains how to manage database connections in ATLAS using the Database Connection Manager. You will learn how to add, remove, and view properties of database connections.
For information on how to setup and configure SQL Server and SQL Race databases, please refer to the [setup guide](../../../../store/sqlrace/installation.md).

## Opening the Database Connection Manager
You can open the Database Connection Manager in two ways:
- Select **Tools > Database Connection Manager** from the Menu Bar.
- Right-click **SQLRace Databases** in the Session Source panel within the Session Browser and select **Connection Manager**.
## Adding a Database Connection
1. Click the **Add** button.
2. Enter the required details:
- **Server Name**: The server hosting the database.
- **Database Name**: The name of the database.
- **Friendly Name** (optional): A user-friendly name for the database.
- **Root Path**: The folder location of the database file.
3. Click **Test Connection** to verify the details.
4. Click **OK** to save and enable the connection.
## Removing a Database Connection
1. Select the database connection you wish to remove.
2. Click the **Remove** button.
3. Confirm removal by clicking **Yes** or cancel by clicking **No**.
## Viewing Database Connection Properties
1. Select the database connection whose properties you want to view.
2. Click the **Properties** button to display the connection details.
---
# Service Connection Manager
!!! danger "Prototype Functionality"
RTA was released as prototype functionality. As such, the content in these pages is subject to change based on feedback and roadmap changes.
# Service Connection Manager
The Service Connection Manager allows users with an RTA License to manage RTA hosts containing sessions in their indexed sources. This guide explains how to add, remove, edit, import, and export service connections.
## Opening the Service Connection Manager
1. Open the **Session Browser**.
2. Go to the **Indexed Sources** tab.
3. Click the **Add Data Source** button ( ).
4. Select **Service Connections**.
## Adding a Service Connection
1. Click the **Add** button.
2. Enter the following connection details:
- **Friendly Name**: The name displayed in the Sources area of the Session Browser.
- **URI**: The address of the RTA Session host.
3. If not using OAuth 2.0 Authorization:
- Click **Test** to verify the connection.
- If successful, click **OK** to save, or **Cancel** to discard.

4. If using OAuth 2.0 Authorization:
- Enable the OAuth 2.0 checkbox.
- Fill in the required authentication fields.
- Test the connection and click **OK** to save.
Once the connection is set up, enable the **Indexed source** checkbox to retrieve sessions from the host.
## Importing and Exporting Service Connections
- Use the **Import** and **Export** buttons in the Service Connection Properties to share connection files (`.svc`) with other users.
## Removing a Service Connection
1. Select the Service Connection to remove.
2. Click the **Remove** button.
3. Confirm by clicking **Yes**, or cancel by clicking **No**.
## Viewing and Editing Service Connection Properties
1. Select the Service Connection you want to view or edit.
2. Click the **Properties** button to access and modify the connection details.
---
# Markers
Markers define specific points or ranges of time within a session and are fully customizable. Each marker can include annotations and labels to describe its purpose.
**Marker Properties:**
- **Type:** Group/category of the marker.
- **Label:** Short summary of the marker.
- **Description:** Detailed explanation.
- **Start Timestamp:** Optional start time (defaults to session start if omitted).
- **End Timestamp:** Optional end time (defaults to session end if omitted).

!!! tip
To represent a single point in time, set both start and end timestamps to the same value.
**Marker Labels:**
Markers can have multiple labels for additional information. Label properties include:
- **Name:** Computer-readable reference.
- **Label:** Human-readable summary.
- **Description:** Detailed explanation.
- **Value:** Associated value.
- **Format:** Display format (e.g., `%.3f` for three decimal places).
- **Unit:** Measurement unit.
Labels are optional and can be used in any combination.
When reviewing markers in the timeline, labels appear in tooltips on hover. Example:

## Adding Markers Programmatically
Markers can be added via code, such as in simulation models or analysis tools. Example using the SQL Race API:
```c#
var marker = new Marker(markerStartTime, markerEndTime, "High Wind", "windSpeedData",
"A period during which the wind was sustained above 9 m/s");
marker.AddLabel(
new MarkerLabel
{
Label = "Average Speed",
Description = "An average sustained wind speed during this time period",
Value = "9.6382834",
Format = "%.2f",
Unit = "m/s",
Name = "windSpeedDataHighVelocity01"
});
marker.AddLabel(
new MarkerLabel
{
Label = "Direction",
Description = "The direction of the wind during this time period",
Value = "323",
Format = "%i",
Unit = "deg",
Name = "windSpeedDataHighDirection01"
});
session.Markers.Add(marker);
```
> **Reference:** See the [Marker class documentation](https://mat-docs.github.io/Atlas.SQLRaceAPI.Documentation/api/MESL.SqlRace.Domain.Marker.html).
## Using the Markers Tab
The Markers tab in the Laps And Markers Editor displays markers for the active session. Users can:
1. **Add** a new marker
2. **Delete** the selected marker
3. **Go To** the selected marker
4. **Edit** the selected marker
!!! note
In LIVE mode, markers cannot be added, deleted, or edited. Editing is enabled once the session is HISTORICAL.
### Marker Types
- **Point Marker:** Represents a single time point (only Start time set).
- **Range Marker:** Represents a time range (both Start and End times set).
### Adding a Marker
- Click **New** to enable editing.
- By default, the Range checkbox is unticked (point marker).
- Start time defaults to the current cursor time.
- Edit the following fields:
- **Label:** Marker name
- **Description:** Optional
- **Range:** Tick for range marker
- **Start time:** Set as needed
- **End time:** Enabled for range markers
Edit times by typing, using arrows, or dropdown controls.
Use the cursor button to set times to the cursor position.
Reset button restores default/previous values.
Click **Save** to add the marker to the list.
### Marker Selection and Management
- **Delete:** Select a marker and press Delete to remove it.
- **Go To:** Select a marker and press Go To to move the cursor (to the time point for point markers, or midpoint for range markers).
- **Edit:** Select a marker, update details, and press Save to apply changes.
Markers are also available in the Laps dropdown.
Point markers show label and time; range markers show label and duration.
!!! tip
Transient markers can be added via Alarms (see Alarm Set Marker).
---
# Laps
In ATLAS, a Lap is a defined segment of time within a telemetry session—typically corresponding to a vehicle completing a circuit. But laps are not just for motorsport. They are a powerful structuring tool for any time-series data stream where repeated cycles or phases occur.
Laps allow users to:
- Segment sessions into meaningful intervals
- Compare performance across repeated events
- Anchor analysis to specific time windows
- Drive automation in dashboards, alarms, and reports

!!! tip
In LIVE mode the dialog is showing the list of the laps recorded so far,but does not allow to make changes. The duration of the last lap will not be up to date in LIVE mode. As soon as the recording ends and session becomes HISTORICAL, the data will be up to date and editing will be enabled.
**Timeline Session Details**
From ATLAS 11.2.3.460 onwards, users can now add information from session details to the Timeline.
The list of all session details is provided on the right-click context menu on the session in the Timeline.

The selected session details are visible as a tooltip by hovering over the specific session in the Timeline.

The number of session details that a user can add can be defined in Tools > Options > Plugins > F1 Timeline, the
maximum number of session details allowed is 20.
## Why Use Laps?
Laps are essential when:
- You want to compare multiple runs of the same test or event
- You need to isolate performance during specific phases (e.g. warm-up, cooldown, pit stops)
- You’re building dashboards or reports that rely on consistent time windows
- You want to automate workflows based on recurring patterns in the data
**Key Capabilities**
**1. Live Lap Tracking**
During a live session, ATLAS can track laps in real time. This is especially useful in motorsport or test environments where engineers monitor performance lap-by-lap.
- Laps are displayed as they are recorded
- The most recent lap is updated continuously
- Once the session ends, laps become editable
!!! warning
In LIVE mode, laps are read-only. Editing is only enabled once the session becomes HISTORICAL.
**2. Manual Lap Definition**
You can define laps manually using the Laps and Markers Editor. This is useful when:
- The data source doesn’t emit lap markers
- You want to redefine laps based on new criteria
- You’re working with appended or stitched sessions
Manual laps can be:
- *Precise:* down to the millisecond
- *Flexible: *placed anywhere in the session
- *Named:* with custom labels like “Out Lap”, “Pit Entry”, “Cool Down”
**3. Session Navigation**
Laps act as bookmarks in your session. You can:
- Jump to a lap instantly using the Go To button
- Use laps to drive cursor synchronisation across displays
- Filter displays or dashboards to show only data from a specific lap
**4. Comparative Analysis**
Laps are the foundation for overlaying and comparing telemetry data. For example:
- Compare throttle traces across laps
- Analyse tyre temperature evolution lap-by-lap
- Identify anomalies or trends across repeated cycles
ATLAS supports:
- Multi-lap overlays
- Delta comparisons
- Statistical summaries across laps
**5. Integration with Workbooks and Displays**
Laps can be used to:
- Drive conditional formatting (e.g. highlight fastest lap)
- Trigger alarms or annotations in dashboards
- Filter waveforms, histograms, or scatter plots to a specific lap
- Laps are not just metadata—they are active drivers of visualisation and logic in ATLAS.
**6. Out/In Lap Handling**
ATLAS supports special lap types:
- *Out Lap:* typically the first lap after leaving the pits
- *In Lap:* the final lap before returning to the pits
These are useful for:
- Excluding non-representative data from analysis
- Flagging laps with different operational contexts
**7. Appended Sessions and Lap Continuity**
When working with appended sessions (e.g. multiple test runs stitched together):
- Laps are preserved per session
- The first lap of each session is protected from deletion
- You can still define new laps across the combined timeline
This enables:
- Longitudinal analysis across multiple runs
- Consistent lap numbering even across session boundaries
## Advanced Use Cases for Laps in ATLAS
Laps are not just a convenience for motorsport—they are a strategic structuring mechanism for any telemetry-driven workflow. Below are advanced scenarios where laps become critical to extracting value from ATLAS.
### Performance Benchmarking Across Sessions
Laps allow engineers to:
Compare performance across different test runs, even if they span multiple sessions or vehicles.
Use lap overlays to visualise differences in throttle, brake, steering, or system behaviour.
Identify repeatable patterns or outliers in performance.
!!! example
Compare Lap 3 from a baseline test with Lap 3 from a new configuration to quantify gains or regressions.
### Automated Report Generation
Laps can be used as reporting units:
- Generate lap-by-lap summaries of key metrics (e.g. max speed, average temperature, fuel usage).
- Export lap segments for external analysis or compliance documentation.
- Drive templated reports that automatically populate based on lap structure.
!!! tip
This is especially useful in endurance racing, fleet testing, or regulatory validation.
### Triggering Alarms and Events
Laps can be used to:
- Trigger alarms when a parameter exceeds a threshold during a specific lap.
- Suppress alarms during out/in laps or cooldown phases.
- Log events tied to lap transitions (e.g. pit entry, system reset, driver change).
This enables context-aware alerting, reducing false positives and improving signal-to-noise ratio.
### Distance-Based Analysis
Laps enable distance-domain visualisation:
- Plot parameters against distance rather than time.
- Compare how systems behave at the same physical location across laps.
- Useful for track-based testing, proving grounds, or route-based validation.
!!! example
Compare suspension travel at the same corner across multiple laps.
### Session Stitching and Longitudinal Studies
When sessions are appended:
- Laps maintain continuity across stitched sessions.
- Engineers can perform longitudinal analysis across days, drivers, or configurations.
Useful for durability testing, regression analysis, or multi-driver comparisons.
### Custom Lap Logic via Functions
Using ATLAS Functions (FDL), users can:
- Define custom lap logic (e.g. laps based on temperature cycles, not distance).
- Create virtual laps based on system states or external triggers.
- Use laps as inputs to derived parameters or conditional displays.
---
# Overview
Parameters are physical properties that are measured during a Session. Typically, a parameter value is the conditioned signal output of a sensor. Each parameter generates data which is available for display.
Parameters may be combined using Functions to give derived results. The output of a Function can be manipulated and displayed in the same way as a parameter.
Each parameter has a set of properties associated with it that control how it is presented in a Display. These can be edited in the Parameter Properties panel. Functions also have Properties.
Parameters are classified into Groups, aimed at simplifying their organization. Parameter Groups are defined in the data logging system and cannot be changed in ATLAS. Parameter groups are listed in the Parameter Browser.
---
# Using Parameters
## Parameter Browser
The Parameter Browser allows you to select and manage Parameters for the currently selected Display. The available Parameters depend on those recorded in the loaded Session.
**Opening the Parameter Browser**
- Click the Parameter Browser icon on the Browser Toolbar.
- Select **View > Parameter Browser** from the Menu Bar.
- Use the keyboard shortcut **P** with a display selected.
- Right-click anywhere on a Display and choose **Parameter Selection** from the context menu.
**Parameter Browser Layout**

1. **Application Groups Panel (Left)**
- Browse and select Application groups to view their Parameters.
- Expand/collapse groups using arrows or double-click.
- Use "All Groups" if unsure where a Parameter is located.
2. **Search Criteria and Parameters List (Center)**
- Search for Parameters by name or description.
- Restrict search to Slow Row, Virtual Parameters, or Functions.
- Add Parameters to the Display by double-clicking or dragging.
- Select multiple Parameters with Ctrl/Shift + Click.
- When comparing sessions, expand Parameters to see applicable sessions.
3. **Selected Parameters (Right)**
- Shows Parameters added to the current Display.
- Parameters with data are white; those without are greyed out.
- Select a Parameter to highlight it on the Display.
- Press **Delete** to remove a selected Parameter
## Changing Parameter Colour
1. Double-click the Parameter name on a Display to open the Parameter Properties window.
2. In the Appearance section, type a colour name or select from the dropdown.
3. Press **Return** or click to confirm the colour.

## Parameter Aliasing (Changing Parameter Name)
Parameter Aliasing lets you assign custom names to Parameters.
- **Replace Mode:** Substitute original names with a new name in the same group.
```
vCar:ChassisSpeed
```
- **Pick Mode:** Link a new name to one of several source names, with priority order.
```
Speed:ChassisCoverageSq:ATLASGForce
```
Configure aliasing in `aliasing.config` saved at `%userprofile%\documents\McLaren Applied Technologies\`.
!!! warning
After making changes to `aliasing.config`, you must restart ATLAS for the new aliases to take effect.
If a parameter (e.g., `pBrake`) is already present in your workbook and you create an alias (e.g., `BrakePressure`), `pBrake` will remain in the workbook but will no longer be searchable in the Parameter Browser. Only the alias name (`BrakePressure`) will be available for searching. To remove the old parameter name from your workbook, you need to delete it manually.
## Application Groups
Applications organize Parameters into groups (e.g., Bios, Chassis, Engine) for easier navigation. Groups are shown in a tree format in the Parameter Browser.
## Number Formats
Customize how Parameter values are displayed using format strings (similar to C language):
- `[text]%[control][total digits].[decimal digits][format code]`
- Control characters: `+` (show sign), `-` (left justify), `0` (leading zeros)
- Format codes: `f` (float), `d` (integer), `x` (hex lower), `X` (hex upper)
Set formats in the Appearance frame of the Parameter Properties panel.
## Parameter Properties Tool Window
Manage Parameter appearance and behavior:
- **Default:** Core properties from data acquisition.
- **Changed:** Overrides for the current Display.
- **Global:** Applies property value to all instances of the display type in the workbook.

**Editing Properties**
- Open the Parameter Properties tool window.
- Click a property value to edit.
- Right-click the icon next to a value for options:
- Copy Name/Value
- Paste Value
- Show/Hide Description
- Make Global
- Clear Global Value
- Reset to Default
!!! tip
Use the Parameter Browser and Properties tool window to fully customize how Parameters are displayed and behave in ATLAS.
---
# Overview
You can export sessions in multiple ways to suit your workflow.
To export an entire session directly from SQL Race to an SSN2 file, simply right-click the session in the Session Browser and select **Export**. Make sure the session is not currently loaded into a Set before exporting.
For more control—such as exporting specific parameters, laps, or using formats other than SSN2—use the [**Export Manager**](export-manager.md) found in the Tools menu.
The Export Manager lets you create and manage export configurations (see example below). To export, select the desired session from the **Session** dropdown (showing sessions loaded via the Session Browser), choose an export configuration, and click **Export**. The **Status** field will display progress as a percentage and update to **Done** when the export is complete.

---
# Export Manager
The Export Manager helps you extract and save session data for analysis, reporting, or sharing. Use it to customize what data you export, how it's formatted, and where it's saved.
## Why Use the Export Manager?
- **Flexible Data Export:** Choose exactly which session data and parameters you need.
- **Multiple Formats:** Export to Text, Matlab, SSN2, or SQL Race Database.
- **Reusable Configurations:** Save export settings for future use.
- **Efficient Workflow:** Export directly from the Export Manager or the Export Data dialog.

## How to Use the Export Manager
1. **Open Export Data Dialog:**
Start by creating a new Export Configuration.
2. **Select Session:**
Pick the session to export from the drop-down list. Only sessions loaded via the Session Browser are available.
3. **Choose Parameters (Execution Tab):**
- Select specific parameters or use the "All Parameters" checkbox.
- Filter by application group, channel type, or search by name.
- Selected parameters appear in a list below.

4. **Set Timing (Timing Tab):**
- Choose laps to export or specify a custom time range.
- Note: Custom time ranges work for text and Matlab exports. For composite sessions, only the first session is exported.

5. **Select Export Format:**
- Pick your desired format (Text, Matlab 1D/2D, SSN2, SQL Race DB).
- Format-specific options (e.g., column separators for Text) will be enabled as needed.
6. **Configure Destination:**
- For SQL Race Database, select from available databases or add new connections via the Database Connection Manager, then set the **Session Identifier** (defaults to the selected session name).
- For other formats, specify the file path.
7. **Auto Increment:**
- All export types support automatic version numbering to the file name or session identifier for SQL Race. When enabled and an export with that name already exists, the system appends `_1`, and increments the number for subsequent duplicates.

7. **Save and Export:**
- Save your configuration for future use.
- Click "Export" to run the export immediately. Progress is shown next to the Export button.
Use the Export Manager to streamline your data export process and ensure you get the data you need, in the format you want.
### Removing Team Security
As of version 11.4.4.371, Export Manager now allows users to remove team security during export. This enables sharing sessions with trusted external parties (e.g., suppliers) using a generic ATLAS license.
!!! info
- Consortium selection only affects who can open the exported session. As a member of the original consortium, you can choose how data is restricted during export.
- The exported session will only include parameters you have access to under your current license.
- RDA restrictions always remain applied, regardless of consortium changes or “No Consortium” selection.
- This feature is only available when exporting to SQLRace or SSN2 formats.

**How to Remove Team Security During Export:**
1. Open Export Manager and create a new export configuration.
2. Select the session(s) you want to export.
3. Choose the export format: SSN2 or SQLRace.
4. Select consortium restriction options:
- Unchanged – Keeps the current consortium setting from the selected session. This option will change based on the session chosen.
- No Consortium – Removes all team restrictions. The exported session can be opened by any ATLAS license.
- Specific Consortium – Locks the export configuration to one consortium only, even if you later change the session.
5. Confirm export options:
- If “All Parameters” is selected, RDA-locked parameters will not be exported.
6. Click Export or Save.
---
# Overview
Functions in ATLAS are user-defined calculations that operate on Session data. They allow users to extend the capabilities of ATLAS by performing custom computations, automating data processing, and enhancing data visualization.
**Key Features:**
- **Custom Calculations:** Functions enable users to create tailored calculations beyond built-in parameters.
- **Flexible Data Analysis:** By using functions, users can manipulate and analyze data according to specific requirements.
- **Integration:** Functions can be used in Displays, similar to Parameters, and support Parameter Properties for dynamic data representation.
- **C# and MATLAB Functions** As well as functions written in FDL, it's possible to use existing C# and MAT functions without translation.
## How do functions work?
- Functions are written in the Function Definition Language (FDL) using the Function Editor.
- They are stored in SQLRace for persistence and reuse.
- Functions can incorporate expressions, statements, processors (pre-defined functions), DLLs (external code), constants, and comments for documentation.
## Why use functions?
- To automate repetitive calculations.
- To implement complex logic and data transformations.
- To integrate external code via DLLs for advanced functionality.
- To improve clarity and maintainability of data processing workflows.
---
# Function Editor
The Function Editor in ATLAS allows users to create, edit, and view Functions, which are used similarly to Parameters for data manipulation and display. Functions are written in the Function Definition Language (FDL) and can reference Parameters, Constants, other Functions, and Processors.

## Quick Start — Creating Your First Function
1. Open the Function Editor and click New. Default General and Function properties are prefilled.
2. Set General Properties (name, format, units, display min/max). These act like parameter properties for Displays.
3. Insert inputs from the Function Parameter Browser (use search; press Enter or double‑click to insert). You can include Parameters, Constants, Processors, or existing Functions.
4. Write FDL in the Function Definition panel (see sections below).
5. Build `(F6)` to check syntax. Success and errors appear in Function Build Output.
6. Save the Function; it becomes available like any Parameter in Displays.
!!! tip
If your environment does not have Resolve without App Name enabled (Options ▸ Data), use the full parameter identifier (e.g., vCar:Chassis) rather than a short name.
## Opening the Function Editor
- Click the **Function Editor** button on the Browser Toolbar.
- Select **View > Function Editor** from the Menu Bar.
## Function Editor Panels
1. **Function Browser**: Lists existing functions. Select to view properties; double-click to edit code.
2. **Properties**: Displays and allows editing of general and function-level properties.
3. **Function Definition**: Central text editor for writing function code. Each opened function appears in a new tab.
4. **Function Build Output**: Shows build progress, status, and errors.
5. **Function Parameter Browser**: Search and add Parameters, Constants, and Functions to your function.
## Editing Function Properties
### General Properties
- **Parameter Name**: Required. Used as the function's identifier.
- **Description**: Editable only in Function Editor.
- **Identifier**: Unique, read-only, auto-updated.
- **Format**: Output format (default `%5.2f`).
- **Units**: Display units (optional).
- **Display Minimum/Maximum**: Axis scaling (default 0.0/1000, required).

### Function Properties (how and when a Function calculates)
When a Function uses multiple inputs sampled at different times, choose how often and where to compute results:
**Function Mode**
- Instantaneous (On‑the‑fly) — evaluates at every sample point of every input; results are not stored. Default for non‑historical Functions.
- Coverage cursor based — computes from Session start to the coverage cursor; results are stored. Default for historical Functions.
- Leading edge — computes once at the leading edge, skipping gaps.
**Calculation Mode**
- Each sample point
- Fixed frequency (set Calculation Frequency (Hz) explicitly)
- Highest rate
**Additional options**
- Calculate Over Whole Session — compute across the entire Session.
- Interpolate Between Samples — interpolate values off the current sample; if off, uses most recent sample.
- Join Gaps Around Null — joins gaps for instantaneous Functions during recording (no effect on historical data).

## Using the Function Parameter Browser
- Search for Parameters, Constants, or Functions from loaded sessions.
- Filter results by All Groups, Processors, or Constants.
- Add items to your function by double-clicking or pressing Enter.

## Function Build Output
- Displays build success or error messages.
- Syntax errors show line and position for troubleshooting.
- Execution errors are logged and disable the function until resolved.

## Writing Functions in FDL
**Parameters**
Insert Parameters in code with the $ prefix (e.g., $Vcar). Type $ then Ctrl+Space to list or filter available items. You may also insert via the Function Parameter Browser. If Resolve without App Name is off, use full identifiers (e.g., $vCar:Chassis)
**Variables and Arrays**
Define variables by assignment—no declarations needed; scope is per Function. Array subscripts can be expressions. Names can include letters, digits, and underscores, and must not clash with a Constant name.
```
for (i = 0; i < 3; i++) {
cyl[i] = 0;
}
```
**Expressions and Operators**
Expressions compute values using operators with a defined precedence (compatible with POSIX bc). Arithmetic (+ - * / % ^), relational (< <= > >= == !=), boolean (! && ||), bitwise (& ~ | >> <<), unary minus, and increment/decrement forms are supported. Parentheses () force evaluation order. Compound assignments (op=) evaluate the left side once (useful with arrays).
**Statements and Control Flow**
Statements control the sequence of evaluation of Expressions.
| Statement | Description |
|--------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `if (expression) statement1 [else statement2]` | Evaluates `expression`. If non-zero, executes `statement1`; if zero and `else` is present, executes `statement2`. The `else` clause is optional. |
| `while (expression) statement` | Executes `statement` repeatedly while `expression` is non-zero. Evaluates `expression` before each iteration. Loop ends if `expression` is zero or a `break` is executed. |
| `for ([expression1]; [expression2]; [expression3]) statement` | Controls repeated execution of `statement`. `expression1` initializes the loop (first pass only). `expression2` is checked before each iteration; if non-zero, executes `statement`. After each iteration, `expression3` is evaluated. If `expression2` is missing, it defaults to `1`. |
| `break` | Causes a forced exit from the most recent enclosing `while` or `for` loop. |
| `continue` | (Extension) Causes the most recent enclosing `for` loop to start the next iteration. |
| `return(expression)` | Returns the value of `expression` from a function. Always return a value from the first executed function, as Displays use it. |
| `= null` | `null` is a special value meaning "not a number". Displays will not plot or calculate with `null` values. |
> Parentheses `{ }` define a compound statement, allowing multiple statements to be grouped for execution within another statement.
> Newlines (or `;`) separate statements; you can hide a newline with `\\`.
!!! note "null means “not a number”"
Displays don’t plot or compute with null.
Always return a value in the first executed Function (because Displays use it).
**Comments**
Use `/* ... */`. Comments act as delimiters and can span lines; don’t split identifiers with comments.
**Referencing other functions**
You can call previously saved Functions by name followed by (), e.g., `FnSlip()`. Functions are pre‑calculated when a Display opens; Live inputs update incrementally.
For more information on available expressions in FDL view the [Processing Guide](processing.md).
## Working with Constants
Constants live outside Functions (global scope) in default_constants.txt:
`C:\Users\[username]\Documents\McLaren Electronic Systems\ATLAS 9\Config`
They can be numeric or string and are ideal for vehicle characteristics you reference across multiple Functions. If a Constant used by a Function is missing, the interpreter raises an execution error.
**Constant Editor (open from Function Editor ▸ View ▸ Constants)**
- Add — enter Name and Value (string/number) and click Add.
- Update — select, edit Name or Value, then Update (changing Name creates a new Constant).
- Delete — select and Delete (confirm when prompted).

**Types of Constants**
- Default — global, stored in default_constants.txt.
- Session — stored within a specific Session; select Session type, then the Set and Session to view.
## Error Handling
- **Syntax Errors**: Detected during build; must be resolved before use.
- **Execution Errors**: Occur during function run; logged and disable the function.
Errors can also originate from Constants (missing/invalid) and Processors (e.g., invalid interpolation files).
---
# Processors
Processors are compiled pre-defined routines.
They provide functionality that would be hard or slow to implement in FDL.
## Trigonometric
Calculated in _radians_:
* `acos(x)`
* `asin(x)`
* `atan(x)`
* `atan2(x,y)` _(arc tan of `y/x`)_
* `cos(x)`
* `cosh(x)`
* `sin(x)`
* `sinh(x)`
* `tan(x)`
* `tanh(x)`
## Mathematical
Simple scalar calculations:
* `abs(x)`
* `ceil(x)`
* `exp(x)`
* `floor(x)`
* `ln(x)` _(natural logarithm)_
* `log(x)` _(base 10 logarithm)_
* `sqrt(x)`
Calulated against parameters with respect to time (even in distance-mode):
* `derivative(param)`
* `integral(param)`
## Logical
`not(x)` _or_ `!x`
: Returns `TRUE` if `x` is 0, otherwise `FALSE`.
`IsInRange(a, b, epsilon)`
: Returns `1` if `a` is in range of `b`.
`IsGT(a, b)`
: Returns `1` if `a` is greater than `b`, otherwise returns `0`.
`IsGE(a, b)`
: Returns `1` if `a` is greater than or equal to `b`, otherwise returns `0`.
`IsLT(a, b)`
: Returns `1` if `a` if less than `b`, otherwise returns `0`.
`IsLE(a, b)`
: Returns `1` is `a` is less than or equal to `b`, otherwise returns `0`.
## Interpolation
`BiLinearInterpolate(file, x, y)`
: Returns a bi-linearly interpolated result corresponding to `x`, `y` from `file`.
* `x` and `y` are parameter names (e.g. `$vCar`) or expressions
* `file` is the path to a `.3d` file in the format specified below.
??? "Data file format"
The filename must have the extension `.3d`
The content is ASCII text, representing the values of data points in a grid.
Comment lines are prefixed with `#`.
Grid rules:
* The grid must be fully populated and rectilinear but need not be regular
i.e. there may be irregular intervals between ordinates but each intersection of an ordinate must have a data value;
* There must be at least 4 data points in the grid;
* Entries must be ordered within a row such that column range values increase to the right
and within a column such that row range values increase to the bottom;
* Entries on the same line must be separated with tabs or commas;
* Both input values must lie within the grid.
If any of these rules are broken, `BiLinearInterpolate(...)` returns a result of `0` and a warning is displayed when ATLAS first attempts to use the processor.
| Line | Entry | Description |
| ------- | ---------------------------------- | -----------------------------------------------------------------------|
| 1 | _blank , X1, X2, …, Xi_ | _Xi_ = value of column _i_ ordinate |
| 2 | _Y1, Z1,1, Z2,1, … , Zi,1_ | 1st row of table (_i_ columns × _j_ rows), _Yi_ = value of row _j_ ordinate _Zi,j_ = data value at intersection of column _i_ and row _j_ |
| 3 | _Y2, Z1,2, Z2,2, … , Zi,2_ | 2nd row of table |
| … | … | 3rd and successive rows of table |
| _n_ | _Yj, Z1,j, Z2,j,... , Zi,j_ | last row of table |
???+ example
This file…
```
# Example 3d grid
,5,7.5,10
0,1,2,3
10,4,5,6
25,7,8,9
30,10,11,12
```
… creates this table:
Input X Range
5
7.5
10
Input Y Range
0
1
2
3
10
4
5
6
25
7
8
9
30
10
11
12
???+ info "Formulae"
If _Xi <= `x` <= Xi+1_ and _Yj <= `y` <= Yj+1_ then
_Za = Zi,j + ( (`x` - Xj) * (Zi+1,j - Zi,j) / (Xi+1 - Xi) )_
_Zb = Zi,j+1 + ( (`x` - Xj) * (Zi+1,j+1 - Zi,j+1) / (Xi+1 - Xi) )_
_result = Za + ( (`y` - Yj) * (Zb - Za) / (Yj+1 - Yj) )_
`LinearInterpolate(file, x)`
: Returns a linearly-interpolated result corresponding to `x` from `file`.
* `x` is a parameter name (e.g. `$vCar`) or expression
* `file` is the path to a `.3d` file in the format specified below.
If `x` under or over the limits of the data set then a result extrapolated from the lowest or highest two data points is returned.
??? "Data file format"
The filename must have the extension `.2d`
The content is ASCII text, representing the values of data points in a grid.
Comment lines are prefixed with `#`.
Grid rules:
* There must be at least two pairs of data but there can be as many as required;
* Entries must be ordered with lowest input, first;
* Entries on the same line must be separated with tabs or commas;
* No consecutive pair of inputs may be the same (to prevent divide by zero errors when calculating _m_).
If any of these rules are broken, `LinearInterpolate(...)` returns a result of `0` and a warning is displayed when ATLAS first attempts to use the processor.
| Line | Entry | Description |
| ------- | --------- | -----------------------------------------------------------------------|
| 1 | _Y1, Z1_ | 1st pair (_Y_ = input value, _Z_ = resulting data value); required |
| 2 | _Y2, Z2_ | 2nd pair; required |
| … | … | 3rd and successive pairs; optional |
| _n_ | _Yn, Zn_ | last pair |
???+ example
This file…
```
# Example 2d grid
0,1
10,4
25,7
30,10
```
… creates this table:
| Input range | Data values |
| ------------- | --------------|
| **0** | 1 |
| **10** | 4 |
| **25** | 7 |
| **30** | 10 |
???+ info "Formulae"
* If `x` is between Yi and Yi+1 then _result = mi*(`x` – Yi) + Zi_
* If `x` is below Y1 then _result = m1*(`x` - Yi) + Z1_
* If `x` is above Yn then _result = mn-1*(`x` - Yn) + Zn_
Where mi = (Zi+1 - Zi)/(Yi+1 - Yi)
## Filtering
!!! note
`param` must be a parameter from a data channel or another function, not the result of a calculation:
`Filter(param,freq)`
: Calculates the smoothed value of the parameter.
This is a low-pass filter with a cut-off frequency of `freq`.
`HighPassFilter(param,freq)`
: Calculates the smoothed value of the parameter.
This is a high-pass Filter with a cut-off frequency of `freq`.
`DigitalFilter1(param, B1, B2, A1, A2)`
: Implements a 1st order digital filter using the difference equation
_`A1`*y(n) = `B1`*x(n) + `B2`*x(n-1) - `A2`*y(n-1)_
`DigitalFilter2(param, B1, B2, B3, A1, A2, A3)`
: Implements a 2nd order digital filter using the difference equation
_`A1`*y(n) = `B1`*x(n) + `B2`*x(n-1) + `B3`*x(n-2) – `A2`*y(n-1) - `A3`*y(n-2)_
`DigitalFilter3(param, B1, B2, B3, B4, A1, A2, A3, A4)`
: Implements a 3rd order digital filter using the difference equation
_`A1`*y(n) = `B1`*x(n) + `B2`*x(n-1) + `B3`*x(n-2) + `B4`*x(n-3) - `A2`*y(n-1) - `A3`*y(n-2) - `A4`*y(n-3)_
!!! caution
For all 3 types of digital filter, it is your responsibility to ensure the function is evaluated at the appropriate frequency for the filter coefficients.
The _Fixed Frequency_ calculation mode is recommended to ensure that changes to the parameters sampling rates do not affect filter results.
`MedianFilter(param,n)`
: Calculates the median filter value in a data window of _n/2_ samples either side of the current data point.
`MedianFilter9(param)`
: Calculates the median filter value of a data window 4 points either side of the current data point.
The effect is to remove spikes from the data, where their width is less than 4 data-points.
`MedianFilter17(param)`
: As above, but the data window is 17 points wide, enabling spikes to be filtered out up to 8 data-points wide.
`MedianFilter25(param)`
: As above, but the data window is 25 points wide, enabling spikes to be filtered out up to 12 data-points wide.
`PhaseCompFilter(param, freq)`
: Calculates a phase-compensated filter which does not lag behind its input parameter.
The filter has a cut-off frequency of `freq`.
The phase-compensated filter does not respond well at very low cut-off frequencies, especially for pre-calculated functions.
In this case, the data is filtered at a higher cut-off frequency.
## Special
These perform special operations on data — such as returning information about a recorded parameter — or special actions — such as writing log output.
!!! note
`param` must be a parameter from a data channel (i.e. not the result of a calculation).
`BitOfWord(param, bit)`
: Returns `1` if bit number bit in the parameter `param` is `1`, otherwise returns `0`.
Bits count from `0` and from least significant to most significant.
`ClearLog(logname)`
: Clears the contents of the file path `logname`.
`CurrentLapNumber()`
: Returns the current Lap number.
`IsFirstPass()`
: Returns `TRUE` the first time that the function is used to evaluate a term and returns `FALSE` for successive passes.
Reset when the function is completed.
`IsInError(param)`
: Returns `TRUE` if the parameter value is in error for that parameter (iIndicates that the sensor may be out of range).
`IndexBySample(param, n)`
: Returns the value of parameter `param`, `n` samples forward or backward (`n` –ve).
`IndexByTime(param, t)`
: Returns the value of parameter `param`, `t` seconds forward or backward (`t` –ve).
`LapBestFit(x, y, Or, Os)`
: Returns the best fit line of parameters `x` and `y` with nth order of `Or` and coefficient index of `Os` (i.e. `0` = offset, `1` = slope etc.)
Returns coefficients during current lap.
`LapMax(param)`
: Returns the maximum value of parameter `param` during the current lap.
`LapMean(param)`
: Returns the mean value of parameter `param` during the current lap.
`LapMin(param)`
: Returns the minimum value of parameter `param` during the current lap.
`LapStdDev(param)`
: Returns the standard deviation of parameter `param` during the current lap.
`LapTime(lap)`
: Returns the lap time in seconds of the given lap `lap`.
`LinearRegressionOffset(x, y)`
: Returns Linear Regression Offset for parameters `x` and `y` during current lap.
`LinearRegressionR2(x, y)`
: Returns Linear Regression R2 for parameters `x` and `y` during current lap.
`LinearRegressionSlope(x, y)`
: Returns Linear Regression Slope for parameters `x` and `y` during current lap.
`SamplesMax(param, n)`
: Returns the rolling maximum value of parameter `param` over the previous n samples.
`SamplesMin(param, n)`
: Returns the rolling minimum value of parameter `param` over the previous n samples.
`SessionMax(param)`
: Returns the maximum value of parameter `param` during the whole session.
`SessionMean(param)`
: Returns the mean value of parameter `param` during the whole session.
`SessionMin(param)`
: Returns the minimum value of parameter `param` during the whole session.
`SessionStdDev(param)`
: Returns the standard deviation of parameter `param` during the whole session.
`SetEvent(n, d, g, p, v)`
: Sets an Event at a given time.
* `n` — Name
* `d` — Description
* `g` — Group
* `p` — Priority (0 -2)
* `v` — Volatility (0,1)
`SamplesPerSec(param)`
: Returns the sample rate in Hz being used to sample the parameter.
`TimeIntoLap()`
: Returns the time in seconds from the start of the current lap in the Active Layer.
`TimeIntoSession()`
: Returns the time in seconds from the start of the current session in the Active Layer.
`TimeOfDay()`
: Returns the time in seconds from midnight for the Active Layer Time Position.
`UwLapMean(param)`
: Returns the unweighted Mean value of parameter `param` during the current Lap.
`UwLapStdDev(param)`
: Returns the unweighted Standard Deviation value of parameter `param` during the current Lap.
`UwSessionMean(param)`
: Returns the unweighted Mean value of parameter `param` during the Session.
`UwSessionStdDev(param)`
: Returns the unweighted Standard Deviation value of parameter `param` during the Session.
`WriteToLog (‘logname’, entry)`
: Appends a line to the file `logname` with the text: `FunctionName` & ++tab++ & `entry`
* `FunctionName` = the name of the function in which the processor was executed.
* `entry` = a string enclosed in quotes or an expression which can be evaluated to a numeric value which is converted to a string representing the value to 8 or more digits.
## Operator Order of Precedence
* `||` boolean operator _(left associative)_
* `&&` boolean operator _(left associative)_
* `!` boolean operator _(non-associative)_
* `<`, `<=`, `>`, `>=`, `==`, `!=` relational operators _(left associative)_
* `=` assignment operator _(right associative)_
* `+` and `-` operators _(left associative)_
* `*`, `/` and `%` operators _(left associative)_
* `^` operator _(right associative)_
* unary `-` operator _(non-associative)_
* `++` and `--` operators _(non-associative)_
## Mathematical Operators
`-` _expr_
: The result is the negation of the expression.
_expr_ `+` _expr_
: The result of the expression is the sum of the two expressions.
_expr_ `–` _expr_
: The result of the expression is the difference between the two expressions.
_expr_ `*` _expr_
: The result of the expression is the product of the two expressions.
_expr_ `/` _expr_
: The result of the expression is the quotient of the two expressions.
_expr_ `%` _expr_
: The result of the expression is the remainder of the division.
`^` _expr_
: The result of the expression is the value of the first expression raised to the second expression.
The second expression must be an integer.
`(` _expr_ `)`
: Alters the standard precedence to force the evaluation of the expression, e.g. a + b / c is not the same as (a + b) / c.
## Variable Operators
`var` refers to either a simple or an array variable.
A simple variable is just a name; an array variable is specified as `name[expr]` (array subscript may be an expression).
`++`_var_
: The variable is incremented by one and the new value is the result of the expression.
`--`_var_
: The variable is decremented by one and the new value is the result of the expression.
_var_`++`
: The result of the expression is the value of the variable and the variable is then incremented by one.
_var_`--`
: The result of the expression is the value of the variable and the variable is then decremented by one.
_var_ `=` _expr_
: The variable is assigned the value of the expression.
_var_ **_op_**`=` _expr_
: This is equivalent to _var_ `=` _var_ **_op_** _expr_ with the exception that the _var_ part is evaluated only once.
This can make a difference if var is an array.
**_op_** is one of the mathematical operators `+`, `-`, `*`, `/`, `%` or `^`.
## Relational Operators
Relational expressions evaluate to either `0` (if the relation is false) or `1` (if the relation is true).
These may appear in any legal expression.
_expr1_ `<` _expr2_
: The result is `1` if _expr1_ is strictly less than _expr2_.
_expr1_ `<=` _expr2_
: The result is `1` if _expr1_ is less than or equal to _expr2_.
_expr1_ `>` _expr2_
: The result is `1` if _expr1_ is strictly greater than _expr2_.
_expr1_ `>=` _expr2_
: The result is `1` if _expr1_ is greater than or equal to _expr2_.
_expr1_ `==` _expr2_
: The result is `1` if _expr1_ is equal to _expr2_.
_expr1_ `!=` _expr2_
: The result is `1` if _expr1_ is not equal to _expr2_.
## Boolean Operators
The result of all boolean operators is either `0` or `1` (for `false` and `true`), as in Relational expressions.
Any non-zero value is treated as `1`.
`!` _expr_
: The result is `1` if _expr_ is `0`, otherwise `0`. (`NOT`)
_expr_ `&&` _expr_
: The result is `1` if both expressions are non⌀zero, otherwise `0`. (`AND`)
_expr_ `||` _expr_
: The result is `1` if either expression is non⌀zero otherwise `0`. (`OR`)
## Bitwise Operators
`~`_expr_
: Bitwise `NOT`
_expr_ `&` _expr_
: Bitwise `AND`
_expr_ `|` _expr_
: Bitwise `OR`
_expr_ `>>` _expr_
: Shift right
_expr_ `<<` _expr_
: Shift left
---
# Using DLLs
## Advanced: Using DLLs
For complex logic, you can write functions in **.NET languages** like C# and import them as DLLs.
### Key Requirements
- Implement `IDotNetFunction` interface.
- Place DLLs in:
`%USERPROFILE%\Documents\McLaren Electronic Systems\SQL Race\Functions`
- Restart ATLAS to register.
## Constants
Constants are reusable values defined outside functions.
- Stored in `default_constants.txt`
- Managed via the **Constants Editor**
- Types: **Default (global)** and **Session-specific**
Use them to avoid hardcoding values like gear ratios, thresholds, or vehicle dimensions.
## Testing & Debugging
### Building Functions
- Press `F6` or click **Build Function**.
- Errors appear in the **Build Output** panel.
### Refreshing Calculated Parameters
- Go to `Tools > Refresh Calculated Parameters`.
- Choose **Workbook** or **Page** scope.
!!! warning
Avoid full refreshes on live data to reduce CPU load.
## Best Practices
- Use **Fixed Frequency** mode for digital filters.
- Use **comments** (`/* ... */`) to document logic.
- Use **SessionMean()**, **LapMax()**, etc. for performance analytics.
- Avoid overloading live sessions with too many functions.
---
# Overview
Alarms in ATLAS let you define conditions over live or historical data; when a condition is met, ATLAS takes one or more actions (e.g., log, warn, pop‑up, or set a marker). Alarms evaluate on every incoming sample of the parameter(s)/event(s) you specify.
Alarms can also be defined in the Alarms.xal file
## Key Concepts
Alarm groups contain related alarms, and all alarms in a group can be disabled in one go at the group level.
An alarm is defined where a condition becomes true. Alarms can be run on:
- Live: Runs continuously as telemetry is received.
- Manual: Runs on-demand over a historical session.
- Load Session: Execute the alarm automatically on session load
!!! note
Alarms triggered on `load session` will not execute if sessions have been loaded as part of a workbook.
An alarm must be part of an alarm group.
---
# Using Alarms
## Creating a new alarm
On the alarm itself you can define behaviour, conditions and actions.
To create a new alarm go to `Tools -> Alarm Editor` and create or select an alarm group and then click `New Alarm`.

You can double click an alarm group to change which sets are active for the alarms in that group. This means that even if the condition of an alarm is met, it will not trigger from the parameters in that set if the group is not active for that set.

## Alarm Properties
### Alarm Conditions
A parameter condition has a primary (required) and a secondary (optional) condition. The primary condition is the main condition that must be met for the alarm to trigger. The secondary condition can be used to add additional criteria that can also be satisfied for the alarm to activate.
An event condition is based on an event ID and does not have primary or secondary conditions.
**Primary Conditions**
`Parameter + Operator + Value`
**Secondary Conditions**
`Logical Operator + Parameter + Operator + Value`
**Event Condition**
`Event ID`

### Alarm Actions
Actions are what happens when an alarm is triggered.
**Warn**
If Warn is selected as an action, the Status Bar shows a running count and the last five raised alarms.

**Audio Warning**
If Audio Warning is selected as an action, a sound plays when the alarm triggers. You can configure the sound as None, Text-to-Speech, or Sound effect.
**Pop-up**
If PopUp is an action, a dialog displays when the alarm triggers. Pop‑ups are configured in Options → Plugins with three modes: Per Alarm (reuse per alarm), Per Occurrence (new for each trigger), Shared (one shared dialog for subsequent triggers).

**Log**
If Log is an action, entries are written to Alarm.log.
**Set Marker**
If Set Marker is an action, ATLAS places a transient point marker at the trigger time/distance, labeled with the Alarm Name and using the Comment as description. These markers are not persisted and are removed when the session unloads; you can view them via the Graphical Timeline dropdown and in [Laps and Markers Editor](../handling-data/laps-markers/markers.md).

## Monitoring
Each triggered alarm will log in the Summary, listing priority, time, name, set, session and lap. Selecting an alarm in the Summary will highlight the trigger time in the session.

---
# Overview
ATLAS Viewer displays are visual components that show telemetry data from your sessions. Each display specialises in presenting data in a specific format — from time-series waveforms to numeric readouts, bar gauges, scatter plots, and more. You can add multiple displays to a workbook page, dock or float them, and save layouts in workbooks.

!!! info "20+ Display Types"
ATLAS includes over 20 display types, each optimised for specific analysis tasks. Choose the right display for your data visualisation needs.
## Adding a Display
=== "Quick Access"
Press `Ctrl+Q` twice, type the display name, press `Enter`
:zap: **Fastest** — searchable, works from anywhere
=== "Display Toolbar"
Click the display icon on the toolbar. Hover to see display names.
:mouse: **One click** when you know the icon
=== "Menu"
**File** > **New** > **Display** and select the display type
:books: **Browse** all available displays
!!! tip "Pro Tip"
Use `Ctrl+Q` twice for fastest access. It's searchable and works from anywhere!
## Display Comparison
| Display Type | Purpose | Key Features | Max Parameters |
|--------------|---------|--------------|----------------|
| [**Waveform**](waveform.md) | Multi-parameter time/distance traces | Interactive legend, reference cursor, autoscale, event markers, live telemetry | 100 (default, adjustable) |
| [**Scatterplot**](scatterplot.md) | 2D plot of Y vs X, optional Z colour mapping | Best-fit/reference lines, up to 5 parameter sets, custom draw styles | 24 |
| [**Histogram**](histogram.md) | Distribution of a single parameter | Spectral/cumulative modes, adjustable bins, auto-refresh | 1 |
| [**FFT**](fft.md) | Frequency spectrum of a single parameter | Window functions, dB scale, peak markers, zoom | 1 |
| [**Loadmap**](loadmap.md) | Pseudo-3D heatmap of time in parameter ranges | Adjustable buckets, colour bar, lap refresh | 2 |
| [**Surface Map**](surface.md) | Interactive 3D mesh graph | Rotate/zoom, axis/grid customisation, requires .3d file | 2 |
| [**Numeric**](numeric.md) | Instant numeric readouts | Auto-sizing text, colour thresholds, grid layout | 150 |
| [**Bar**](bar.md) | Vertical gauge bars with numeric values | Real-time updates, custom refresh/background | 16 |
| [**Block Bar**](block.md) | Minimalistic single-parameter bar | Conditional/gradient colouring, orientation options | 1 |
| [**Bit**](bit.md) | Status bits with custom colours/labels | Boolean/status flags, .bcg file support, layout options | 20 |
| [**Summary**](summary.md) | Lap-based statistics table or plot | Min/Max/Mean per lap, resizable columns, snapshot export | Multiple |
| [**Circuit**](circuit.md) | Track map with car position | Sectors/segments, shaded timebase, circuit editor | 1 |
| [**PCU Dash**](pcu.md) | Steering wheel display simulator | Multiple dash types, auto-load config | Default only |
| [**Event**](event.md) | ECU events with priority and snapshots | Priority filtering, masking, row colouring | 100 |
| [**Error**](error.md) | Live ECU error monitoring | Status tracking, filtering, double-click to jump | N/A |
| [**Notepad**](notepad.md) | Free-text session notes | Custom fonts/colours, snapshot/copy | N/A |
| [**Bing Map**](map.md) | Satellite map of GPS location | Zoom/scale, GPS formats, lock map centre | N/A |
| [**Web Browser**](web.md) | Embedded browser | Live feeds/web content, show/hide controls | N/A |
| [**Countdown Timer**](countdown.md) | Countdown clock or time offset | Custom text, font/colour options | N/A |
| [**Video**](video.md) | Synchronised video playback | In-car camera, event correlation | N/A |
## Switching Between Sessions
If you have multiple sessions loaded (Compare Sets):
| Action | Shortcut | Result |
|--------|----------|--------|
| Switch selected display | `Shift+` | Changes active display only |
| Switch entire page | `Ctrl+` | All displays on page switch together |
| Click coloured tag | Mouse click | Menu shows available sets |
When a whole page shows the same set, a coloured line appears across the page header.
## Display Tools
### Display Properties
Every display has a **Display Properties** panel (press `D` or right-click > **Display Properties**) for formatting options specific to that display type.
Properties can be:
- **◻️ Square**: Default value. Reset to default with the reset button.
- **♦️ Diamond**: Changed for this instance only.
- **⚪ Circle**: Global setting — affects all future instances of that display type.

Right-click any property to make it global, clear global assignment, or reset to default. The meaning of each property is shown at the bottom of the Display Properties window when selected.
!!! warning "Global Properties"
Global properties affect ALL future displays of that type. Use carefully!
### Zoom
There are two types of zoom operation:
- **X only**: Zoom the X-axis only. Changes the Duration on the Timebase (Waveform Display only).
- **X and Y**: Click and drag a Zoom Box to zoom both axes in Waveform or Scatterplot displays.
In a Waveform Display, drawing from top-to-bottom creates an X+Y zoom box; drawing bottom-to-top creates an X-only zoom strip. In a Scatterplot Display, the zoom region is always a box regardless of direction.
### Columns
Some displays (e.g., Event, Error, Summary) have resizable/hideable columns. Hover at a header edge to resize; double-click to auto-fit. Fully hiding a column by shrinking width to zero can be reversed by grabbing the split-line cursor and dragging open.
### Toolbar
The display toolbar has buttons for adding all displays quickly to the current workbook page. Hover over an icon to see its name; click to add.

### Context Menus
Right-click on most displays to access:
- Copy to clipboard
- Export snapshot
- Display properties
- Parameter properties
- Reset zoom/scale
- Display-specific tools
## Adding Parameters
After opening a display, use the **Parameter Browser** to add telemetry channels:
1. Open Parameter Browser (`Ctrl+P` or View menu)
2. Browse or search for parameters
3. Drag parameters onto the display, or select and click "Add to Display"
Many displays allow double-clicking an item (bar, axis, legend row, etc.) to open **Parameter Properties** for fast formatting.
## Live Telemetry
When connected to live telemetry:
- Displays update in real-time
- Waveform scrolls as data arrives
- Numeric/Bar displays show current values
- Pause scrolling by clicking the plot area
## Workbooks
Displays are saved in workbooks which remember:
- Display types and positions
- Parameter selections
- Display properties
- Layout configuration
Save your workbook (`Ctrl+S`) to preserve your display setup for future sessions.
## Quick Reference
| Key | Action |
|-----|--------|
| `Ctrl+Q, Ctrl+Q` | Quick Access Assistant |
| `Ctrl+P` | Parameter Browser |
| `D` | Display Properties |
| `Shift+` | Switch display to Compare Set n |
| `Ctrl+` | Switch page to Compare Set n |
| `Ctrl+S` | Save workbook |
---
For in-depth guidance on parameters, sessions, cursors, workbooks, and common workflows, see the [Working with Displays](essentials.md) guide.
---
# Working with Displays
This guide covers the core concepts and workflows that apply across all display types in ATLAS Viewer. Understanding these will help you work efficiently with any display.
!!! tip "Quick Start"
New to ATLAS displays? Start here to learn the fundamentals, then explore individual display guides for specifics.
## Display Windows
Every display is a window that can be:
- **Docked**: Attached to the main window in a tabbed layout
- **Floating**: Separate window that can move independently (great for multi-monitor setups)
- **Resized**: Drag edges or corners to resize
- **Closed**: Click X button or right-click > Close
Only one display is "selected" at a time (click inside it).
## Display Properties
### Opening Display Properties
- Press `D` when display is focused
- Right-click display > Display Properties
- Toolbar button when display is selected
### Understanding Property Icons
!!! info "Property Status Icons"
**◻️ Square Icon**: Default value — reset with the reset button
**♦️ Diamond Icon**: Changed for this display instance only — other displays unaffected
**⚪ Circle Icon**: Global setting — applies to ALL displays of this type, including future ones
### Making Properties Global
1. Right-click the property name
2. Select "Make Global" — property becomes global (⚪ icon)
3. All future displays of that type will use this value
To remove global status: right-click the property > "Clear Global".
!!! warning
Global properties affect ALL future displays of that type. Use carefully!
The meaning of each property is shown at the bottom of the Display Properties window when selected.
## Working with Parameters
### Parameter Browser
The Parameter Browser is your main tool for finding and adding parameters.
**Opening**:
- Press `Ctrl+P`
- View menu > Parameter Browser
- Usually docked on the left side
**Features**:
- :mag: **Search**: Type in search box to filter the parameter list (supports partial matches)
- :star: **Favourites**: Star frequently used parameters for quick access from the Favourites tab
### Adding Parameters to Displays
=== "Drag and Drop"
Find parameter in Parameter Browser, click and drag onto display, release to add.
:mouse: **Fastest** for single parameters
=== "Add Button"
Select parameters in Parameter Browser, click "Add to Display" button.
:heavy_check_mark: **Best** for multiple parameters
=== "Double-Click"
Double-click parameter in browser to add to active display (some displays only).
:zap: **Quick** single-parameter add
### Parameter Properties
Edit individual parameter settings by double-clicking the parameter in the display, or right-click > Properties.
| Setting | Description |
|---------|-------------|
| **Colour** | Parameter trace or text colour |
| **Format** | Decimal places, hex, scientific |
| **Units** | Display units |
| **Scale** | Y-axis range (waveforms) |
| **Thresholds** | Warning and critical levels |
| **Post-Processing** | Smoothing, filtering, differences |
### Removing Parameters
- Select parameter in display
- Press `Delete`, or right-click > Remove Parameter
!!! note
Some displays allow hiding parameters instead of deleting — hidden parameters can be restored.
## Display Layout and Organisation
### Pages
Workbooks contain pages; pages contain displays.
- **Create pages**: Right-click page tabs > New Page (or duplicate an existing page)
- **Name pages**: Right-click page tab > Rename — use descriptive names like "Overview", "Sector 1", "Gearbox"
- **Organise**: Group related displays on the same page; use separate pages for different analysis areas
### Docking and Floating
**Docking**:
- Drag display by title bar
- Blue target indicators show dock locations
- Drop on target to dock
**Floating**:
- Drag display outside dock area to create an independent window
- Perfect for multi-monitor setups
- Drag back to dock area to re-dock
### Resizing
- Drag edges to resize
- Drag corners to resize proportionally
- Double-click title bar to maximise/restore
- Docked displays share space with neighbours
## Session Management
### Loading Sessions
**Single Session**:
1. File > Open Session
2. Browse to session file
3. Session loads into Compare Set 1
**Multiple Sessions** (Compare Sets):
1. File > Add to Compare Set
2. Choose set number (1-8)
3. Session loads into specified set
4. All displays can switch between sets
### Switching Between Sessions
| Action | Shortcut | Result |
|--------|----------|--------|
| Switch selected display | `Shift+` | Changes active display only |
| Switch entire page | `Ctrl+` | All displays on page switch together |
| Click coloured tag | Mouse click on title bar | Menu shows available sets |
When a whole page shows the same set, a coloured line appears across the page header.
### Compare Sets
Compare Sets let you analyse multiple sessions:
- Load up to 8 sessions simultaneously
- Compare different laps, runs, or drivers
- Each display can show a different set
- Switch quickly with keyboard shortcuts
## Cursor Control
### Moving the Cursor
=== "Mouse"
Click in display to position cursor. Drag cursor line to move.
:mouse: **Quick** positioning
=== "Keyboard"
| Keys | Action |
|------|--------|
| `←` / `→` | Move by one sample |
| `Shift+←` / `Shift+→` | Move faster |
| `Home` | Jump to session start |
| `End` | Jump to session end |
| `Page Up` / `Page Down` | Larger steps |
:keyboard: **Precise** control
=== "Direct Entry"
Right-click cursor area, enter specific time or distance, press `Enter` to jump.
:dart: **Exact** positioning
### Cursor Synchronisation
!!! info "Synchronised Cursors"
The cursor is synchronised across displays:
- Moving cursor in one display moves all displays
- All displays show data at the same time point
- **Exception**: Displays showing different sessions
## Workbooks
### What are Workbooks?
Workbooks save your entire workspace:
- All pages and displays
- Display positions and sizes
- Display properties
- Parameter selections
- Compare set configuration
### Saving and Opening
- **Save**: `Ctrl+S` or File > Save
- **Save As**: File > Save As (useful for creating templates)
- **Open**: File > Open Workbook (restores exact workspace; prompts if sessions not found)
### Workbook Templates
Create reusable templates:
1. Set up displays and layout
2. Configure all properties
3. Save As with a descriptive name
4. Use as starting point for similar analysis
Keep templates in a dedicated folder for easy access.
## Common Workflows
=== "Quick Session Review"
1. Open workbook template
2. Load session
3. Cursor through interesting areas
4. Make notes in Notepad display
:fast_forward: **Goal**: Rapid session inspection
=== "Multi-Lap Comparison"
1. Load laps into compare sets
2. Switch displays to each lap
3. Use Reference Cursor to compare points
4. Note differences in Notepad
:left_right_arrow: **Goal**: Identify lap differences
=== "Event Investigation"
1. Open Event Display
2. Select event of interest
3. Cursor jumps to event time
4. Check parameters in other displays
:mag: **Goal**: Diagnose issues
=== "Dashboard Monitoring"
1. Create Numeric Displays for key parameters
2. Set warning/critical thresholds
3. Position displays for visibility
4. Save as monitoring workbook template
:bar_chart: **Goal**: Live monitoring station
## Performance Tips
For smooth operation:
- Limit parameters per display to a reasonable number
- Use appropriate refresh rates
- Close unused displays
- Disable features you don't need (e.g., interpolation)
- For large sessions, zoom to area of interest and enable sub-sampling where available
- Use Summary Display instead of Waveform for statistics over large ranges
## Best Practices
!!! tip "Organisation"
:file_folder: **Organise with pages**: Group related displays on separate pages
:floppy_disk: **Use templates**: Create workbooks for common analysis tasks
:bookmark: **Name sessions clearly**: Easy to identify later
!!! tip "Efficiency"
:keyboard: **Learn shortcuts**: Faster than mouse for frequent actions
:arrows_counterclockwise: **Save often**: Don't lose your workspace
:broom: **Clean up**: Close displays you're not using
!!! tip "Analysis"
:memo: **Document findings**: Use Notepad display for notes
:rocket: **Start simple**: Add complexity as needed
:chart_with_upwards_trend: **Work methodically**: Systematic approach beats random exploration
## Troubleshooting
??? question "Display not updating?"
- Check session is loaded
- Verify parameter is available in session
- Check refresh rate in display properties
- Ensure display is focused (click it)
- Check you're not paused
??? question "Can't add more parameters?"
- Each display has a maximum parameter limit (see [Display Comparison](index.md#display-comparison))
- Check parameter exists in loaded session
- Verify display supports that parameter type
??? question "Display shows 'No Data'?"
- Check cursor is in valid data range
- Verify parameters have data at cursor position
- Ensure session is properly loaded
- Check time/distance mode is correct
??? question "Properties won't save?"
- Save workbook after changes (`Ctrl+S`)
- Check workbook is not read-only
- Verify write permissions to workbook location
??? question "Display performance is poor?"
- Reduce number of visible parameters
- Lower refresh rate
- Disable expensive features (interpolation, etc.)
- Close other displays temporarily
- Check system resources
??? question "Display looks cluttered?"
- Hide parameters temporarily (don't delete)
- Use Distribute function (Waveform)
- Adjust font sizes and layout
- Reduce number of visible parameters
??? question "Cursor not moving?"
- Click to focus the display
- Check if display supports cursors
- Verify session is active
---
# Bar
Instantaneous value of selected parameters as vertical bars with numeric readouts. Updates in real time with telemetry. Up to 12 parameters. Double‑click a bar to edit that parameter’s properties.

## Adding a Bar Display
To add a Bar Display to a Page do one of the following:
- Click the Bar Display button on the Display Toolbar.
- Click `File > New > Display` and select Bar Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Bar Display.
You can now use the Parameter Browser to add some Parameters to set up the display as required.
Any number of bar graph displays can be opened at the same time.
The display updates in real time with the reception of Telemetry data.
---
# Bit
Status bits of one or more parameters, with configurable On/Off colours, labels, and captions per bit. You can pick which bits are active for each parameter.

## Adding a Bit Display
To add a Bit Display to a Page do one of the following:
- Click the Bit Display button on the DisplayToolbar.
- Click `File > New > Display` and select Bit Display.
- Press `Ctrl + Q` twice to use the QuickAccess Assistant and select New Bit Display.
To select which Bits you want to show for each Parameter:
1. Right click the column on the Display for the required Parameter.
2. Select Show Bit Options or Double Click a Parameter name on the Display headers
3. Choose from the following options for each Bit:
| Option | Description | Default Value |
|-------------|--------------------------------------------------------|--------------------|
| **Active** | Whether the Bit is shown or not | — |
| **Caption** | Text caption for that Bit | — |
| **OffColour** | Colour displayed when that Bit is off | Red |
| **OffLabel** | Text label displayed when that Bit is off | — |
| **OnColour** | Colour displayed when that Bit is on | Green |
| **OnLabel** | Text label displayed when that Bit is on | — |
You can also quickly set up your Bit Display by loading a `.bcg` (Bit Configuration) file.
### Using a Bit Configuration File
- The location of the `.bcg` file can be set in **Tools > Options > Plugins > Bit Display**.
- Each Bit Display can be configured using the same `.bcg` file, with settings based on the parameter shown.
#### File Format
Each line in the `.bcg` file configures bits for a specific parameter. All bit definitions for a parameter must be on the same line.
**Format:**
```
ParameterName,BitNumber,Show(1|0),Caption,OffColor(decimal),OnColor(decimal),OffLabel,OnLabel,BitNumber,Show(1|0),Caption,OffColor(decimal),OnColor(decimal),OffLabel,OnLabel,...
```
- `ParameterName`: Name of the parameter.
- `BitNumber`: Zero-based index of the bit.
- `Show`: `1` to show, `0` to hide.
- `Caption`: Text caption for the bit.
- `OffColor` / `OnColor`: Color when bit is off/on, as a decimal value of the C++ `COLORREF` format (`0x00BBGGRR` reordered to `0x00RRGGBB` and converted to decimal).
- `OffLabel` / `OnLabel`: Text label when bit is off/on.
**Example:**
```
Status,0,1,Power,255,65280,Off,On,1,1,Error,255,65280,No,Yes
```
For custom colors, convert the hex value to decimal after reordering. For example, `0x00877D7C` becomes `0x007C7D87` and is written as `8158599`.
!!! note
The Bit Display will use the `.bcg` file only after you double-click the display and check the **Use bit config file?** option. The display will then refresh with the new configuration.
---
# Block
Minimal single‑parameter bar—quick, graphic visualization without numeric clutter. Optional gradient colour and conditional colouring using parameter warning/critical thresholds.

## Adding a Block Bar Display
To add a Block Bar Display to a Page do one of the following:
- Click the Block Bar Display button on the Display Toolbar.
- Click `File > New > Display` and select Block Bar Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Block Bar Display.
---
# Circuit
Track map from a Circuit Definition file, with cursor‑synchronised car position indicator and optional sectors/segments; a shaded Timebase Region on the map mirrors the Waveform timebase.

## Adding a Circuit Display
To add a Circuit Display to a Page do one of the following:
- Click the Circuit Display button on the Display Toolbar.
- Click `File > New > Display` and select Circuit Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Circuit Display.
You can now use the Parameter Browser to add some Parameters to set up the display as required. The current cursor position is shown on the circuit if you add the sLap Parameter.
## Circuit Editor
The Circuit Editor is a tool within ATLAS that allows users to create and modify Circuit Definition files. These files control how a racing track is visually represented and subdivided into Segments (Corners and Straights) and Sectors, ensuring consistency across displays such as Circuit Display and Waveform.
- **Segments**: Engineering-relevant divisions of the lap, typically representing corners (green) and straights (yellow).
- **Sectors**: User-defined partitions of the lap, often used for timing and analysis, with customizable colors.

### File Management
- Circuit definitions are stored in a user-configurable folder (set in Options ▸ Plugins).
- The Circuit Display’s dropdown menu is populated from files in this folder.
- Supported formats:
- `.cktx`: ATLAS Circuit Definition (preferred; always written on save).
- `.ckt`: Atlas 9 legacy format (can be opened and converted to `.cktx`).
### Using the Editor
You can open the Circuit Editor in two ways:
1. Via **Tools ▸ Circuit Editor**, then select a `.cktx` or `.ckt` file.
2. By right-clicking an existing Circuit Display and choosing **Edit**.
- **Save**: Writes the current definition in `.cktx` format. Legacy `.ckt` files are converted.
- **Save As**: Allows duplication under a new name, useful for creating event-specific variants.
The editor is organized into three tabs, each with a live preview:
1. **General Tab**
- Set the circuit’s name, add documentation notes, and specify total length.
- Preview shows the circuit as it will appear in displays.
2. **Segments Tab**
- Define the sequence of corners and straights.
- Add, rename, or delete segments; adjust boundaries by dragging or entering values.
- Segments are color-coded and labeled for clarity.
3. **Sectors Tab**
- Partition the lap for timing/analysis.
- Add, rename, recolor, or delete sectors; adjust boundaries interactively.
- Sectors are independent of segments.
## Workflows
- **Create Segments**: Open a circuit, switch to Segments, insert boundaries, set types and names, adjust distances, and save.
- **Define Sectors**: Switch to Sectors, insert splits, name and color sectors, adjust boundaries, and save.
- **Correct Mistakes**: Use Add/Delete without moving the cursor to revert changes.
- **Document**: Update the circuit’s name and notes for clarity and team standards.
!!! tip "Tips & Best Practices"
- Keep segment/sector boundaries monotonic and within adjacent limits.
- The Start/Finish line is fixed; plan boundaries accordingly.
- Use **Save As** for alternate layouts to avoid overwriting base definitions.
- Undo is limited; use Add→Delete cycles for safe reversion.
## Integration Checklist
- Ensure Circuit Display shows the correct circuit, segments, sectors, and orientation.
- Waveform pages should use the intended circuit definition and enable Circuit Stripe as needed.
- Confirm the Options ▸ Plugins folder points to the correct repository for shared access.
---
# Countdown
A configurable countdown clock (or Time Offset from now) with custom text pre‑ and post‑expiry.

| Option | Description |
|----------------|---------------------------------------------------------------------------------------------|
| **Timer Mode** | Choose between Countdown Timer (counts down to set time) or Time Offset (shows offset time).|
| **ExpiryHour** | Hour of expiry for the countdown timer. |
| **ExpiryMinute** | Minute of expiry for the countdown timer. |
| **OffsetHours** | Hours offset from current time for Time Offset mode. |
| **OffsetMinutes** | Minutes offset from current time for Time Offset mode. |
## Adding a Countdown Timer Display
To add a Countdown Timer Display to a Page do one of the following:
- Click the Countdown Timer Display button on the Display Toolbar.
- Click `File > New > Display` and select Countdown Timer Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Countdown Timer Display.
---
# Error
ECU errors during live connection. Columns include Status (Forthcoming/Current/Logged, with colours), Name, Description, Timestamp. Double‑clicking an error jumps the timeline cursor to first occurrence. Logged errors persist until ECU reset based on your choice (per Lap or Session).

## Adding an Error Display
You can add an Error Display to a Page using any of the following methods:
- **Display Toolbar:** Click the Error Display button.
- **Menu:** Go to `File > New > Display` and select Error Display.
- **Quick Access Assistant:** Press `Ctrl + Q` twice, then select New Error Display.
## Error Row Details
Each error is displayed as a row with the following columns:
- **Status Indicator:**
A coloured symbol representing the error status:
- *Forthcoming*: Error expected to occur later in the session.
- *Current*: Error is actively occurring (displayed in red).
- *Logged*: Error occurred previously but is no longer active (displayed in white).
*Note:* The error text colour matches the status indicator.
- **Name:**
Displays the error code and name.
- **Description:**
Provides a brief description of the error.
- **Status:**
Indicates the error's relation to the session timeline:
- *Forthcoming*: Will occur later in the session.
- *Current*: Actively occurring error.
- *Logged*: Previously occurred, now inactive.
- **Timestamp:**
Shows the time when the error was first detected.
## Error Status Behaviour
- When an error is detected, it appears in red text with a *Current* status.
- If the sensor returns to normal, the error switches to *Logged* status and white text.
- Logged errors remain visible and will revert to *Current* if the same error is detected again.
---
# Event
ECU Events (from program version files defined in Options), with Priority (High/Medium/Low), Timestamp, Group, Id, Description, and parameter snapshots at the event time. Tabs allow quick filtering by priority or “Masked”. Clicking an event moves the timeline cursor to that time/distance.

## Adding an Event Display
- Use the Event Display button on the DisplayToolbar.
- Navigate to File > New > Display and select Event Display.
- Press Ctrl + Q twice to open the QuickAccess Assistant and select New Event Display.
**Event Display Overview**
Each event appears as a row with the following columns:
- **Priority Indicator**: Symbol showing event priority (High, Medium, Low).
- **Timestamp**: Time when the event occurred.
- **Group**: Parameter group name related to the event.
- **Id**: Unique integer for diagnostics.
- **Description**: Text describing the event.
- **Parameter Name**: Value of selected parameters at event time.
**Filtering and Customization**
- Tabs at the top allow filtering by priority: All, High, Medium, Low, Masked.
- Column widths are adjustable (see "Columns in Displays").
- Warning ranges for parameters can be set in the Appearance section of Parameter Properties.
**Display Options**
- By default, text uses the foreground colour.
- If "Show Warning Colours" is enabled in Display Options, parameter text changes colour when in the warning range.
- If "Critical" is checked: Critical colour (default Red) is used.
- If "Critical" is unchecked: Non-Critical colour (default Blue) is used.
---
# FFT
!!! danger "Preview Functionality"
The FFT Display is currently a preview feature. As such, the content in this page is subject to change based on feedback and roadmap changes. This display is available from ATLAS [v11.5.4.230](../../../../blog/posts/viewer/11.5.4.230-W37.md) onwards.
# FFT Display
Frequency content of a single parameter. The FFT Display takes the samples in the current session timebase and transforms them into a spectrum — magnitude against frequency — so you can see *which* frequencies are present in a signal rather than how it varies over time.

## When to Use FFT Display
:vibration_mode: **Vibration analysis**: Identify the dominant frequencies in an accelerometer or strain channel.
:gear: **Rotational orders**: Relate spectral peaks to shaft, wheel or engine speeds.
:radio: **Noise and interference**: Spot mains hum, sensor noise or aliasing artefacts in a channel.
:chart_with_upwards_trend: **Filter checking**: Confirm that a filtered signal has actually lost the frequencies you expected.
## Enabling the FFT Display
!!! note
The FFT Display is off by default. Enable it in **Tools > Options > General > Preview Features** by ticking **Allow FFT display**, then restart ATLAS. Until you do, the display does not appear on the toolbar, in the **File > New > Display** menu, or in the Quick Access Assistant.
## Adding an FFT Display
To add an FFT Display to a page, use one of the following methods:
- **Display Toolbar:** Click the **FFT Display** button .
- **Menu:** Go to **File > New > Display** and select **FFT Display**.
- **Quick Access Assistant:** Press `Ctrl + Q` twice, then select **New FFT Display**.
## Adding a Parameter
The FFT Display shows **one parameter at a time**.
- Press `P` to open the Parameter Browser and select a parameter, or
- Drag a parameter onto the display from the Parameter Browser or another display.
Dropping a parameter onto a display that already has one **replaces** it — you do not need to remove the old parameter first. The spectrum trace, the fill and the peak markers all take the parameter's colour, and the parameter name is shown at the top of the plot.
## Display Anatomy
- **Header readouts**: `Fs` — the sample rate used for the transform, and `df` — the frequency resolution (the width of one bin). Both appear at the top left once a spectrum has been computed.
- **X-Axis**: Frequency in Hz, from 0 up to the Nyquist frequency (half the sample rate).
- **Y-Axis**: Magnitude, either linear or in dB.
- **Spectrum trace**: The parameter's spectrum, optionally filled below the curve.
- **Peak markers**: Circular markers on the most prominent peaks.
- **Status message**: Replaces the plot when there is not enough data to transform.
## Display Properties
Press `D` or right-click > **Display Properties** to open the property grid.
| Category | Property | Default | Description |
|---|---|---|---|
| General | **Background Colour** | Black | The background colour of the display. |
| FFT | **Logarithmic Scale (dB)** | Off | Switches the magnitude axis between linear and dB. |
| FFT | **Window Function** | Hann | The window applied before the transform: None, Hann, Hamming or Blackman. |
| FFT | **FFT Size** | 1024 | The maximum number of samples used for the transform. |
| FFT | **Show Fill** | On | Shows or hides the shaded area under the spectrum curve. |
| FFT | **Show Peaks** | On | Shows or hides the peak markers. |
### FFT Size
FFT Size sets the *maximum* number of samples fed into the transform. It is limited to the range 64 to 16384 and is always snapped to a power of two: entering a larger value rounds up to the next power of two, entering a smaller one rounds down to the previous one. So typing `1000` gives 1024, and typing `900` when the size was 1024 gives 512.
The size you choose trades frequency resolution against the amount of data summarised:
| FFT Size | Frequency resolution | Use when |
|---|---|---|
| Smaller (64–512) | Coarser | You only need the broad shape of the spectrum. |
| Default (1024) | Balanced | General-purpose analysis. |
| Larger (2048–16384) | Finer | You need to separate peaks that are close together in frequency. |
If the parameter has fewer samples than the FFT Size, the transform still runs at the next power of two above the sample count, and the remainder is zero-padded.
### Window Function
A window function tapers the ends of the sample block before the transform, which reduces the spectral leakage that would otherwise smear a peak across neighbouring bins.
| Window | Character |
|---|---|
| **None** | No tapering. Sharpest possible peak, most leakage. |
| **Hann** | Good general-purpose compromise between peak width and leakage. Default. |
| **Hamming** | Slightly narrower main lobe than Hann, with a higher first side lobe. |
| **Blackman** | Widest main lobe, lowest leakage — best for spotting a small peak next to a large one. |
### Logarithmic Scale
With **Logarithmic Scale (dB)** off, the Y-axis shows linear magnitude and is titled *Magnitude*. With it on, magnitudes are converted to decibels (20 × log₁₀ of the linear magnitude) and the axis is titled *Magnitude (dB)*. The dB view compresses the range, which makes small peaks visible alongside a dominant one.
!!! note
Switching the scale clears and recomputes the spectrum, so the plot blanks briefly.
## Reading the Spectrum
Hover anywhere on the trace to get a tooltip giving the frequency and the magnitude of the nearest point — the frequency in Hz to two decimal places, and the magnitude to four (in dB when the logarithmic scale is on).
The two header readouts tell you what the spectrum is capable of showing:
- **Fs** is estimated from the timestamps of the samples returned for the session, so it reflects the actual logging rate of the parameter. The highest frequency the plot can show is half of it.
- **df** is the spacing between adjacent points on the frequency axis — the sample rate divided by the transform length. Two components closer together than `df` cannot be resolved into separate peaks.
In the screenshot above, a parameter logged at 5000 Hz and the default 1024-point transform give a resolution of 4.88 Hz per bin, over a frequency axis reaching 2500 Hz.
### Peak Markers
With **Show Peaks** on, the display marks the peaks in the spectrum — up to ten of them, chosen by magnitude — with a circular marker. Hover over a marker for its exact frequency and magnitude. Turn **Show Peaks** off for a cleaner trace when you are only interested in the overall shape.
## Zoom and Navigation
| Action | How |
|---|---|
| **Zoom to a region** | Hold the right mouse button and drag a box over the area of interest. |
| **Zoom with the wheel** | Scroll up to zoom in, down to zoom out. The zoom centres on the pointer. |
| **Left-drag zoom** | Right-click > **Zoom Box**, then drag once with the left button. |
| **Undo Zoom** | Right-click > **Undo Zoom**. Steps back one zoom level. |
| **Undo All Zooms** | Right-click > **Undo All Zooms**. Returns to the full spectrum. |
Both axes auto-range until you zoom. Undoing past the first zoom level restores auto-ranging, so the display resumes fitting the whole spectrum as new data arrives.
## Refreshing
The display recomputes when the data it depends on changes — a new session, a new parameter, or a change to any of the FFT properties. Requests are throttled to five a second, and the spectrum is computed over the whole of the current session timebase rather than a cursor window. Changing or removing the session clears the display.
## Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| The FFT Display is not on the toolbar or in the display menu | The preview feature is not enabled, or ATLAS has not been restarted since enabling it | Tick **Allow FFT display** in **Tools > Options > General > Preview Features** and restart ATLAS. |
| "Insufficient data, please select a wider timeline" | The parameter returned too few samples over the session timebase to compute a transform | Widen the timeline, choose a parameter logged at a higher rate, or open a session with a longer timebase. |
| The plot is empty and there are no readouts | No parameter has been added, or the session has no data for it | Press `P` and select a parameter, or drag one onto the display. |
| The peaks you expect are missing or merged | The frequency resolution is too coarse to separate them | Increase **FFT Size**, or switch **Window Function** to Blackman if a large peak is masking a small one. |
| A small peak is invisible next to a large one | Linear magnitude scaling | Turn on **Logarithmic Scale (dB)**. |
## Quick Reference
| Key | Action |
|---|---|
| `D` | Display Properties |
| `P` | Parameter Browser |
| `Ctrl + Q, Ctrl + Q` | Quick Access Assistant |
---
# Histogram
Distribution of a single parameter against time or distance, either Spectral (time/distance in each bin) or Cumulative (≤ each bin). X‑axis range comes from the parameter’s Display Min/Max. Optional % labels on bars and Y‑axis as % or absolute. Refresh per lap in Live Mode.

## Adding a Histogram Display
To add a Histogram Display to a Page do one of the following:
- Click the Histogram Display button on the Display Toolbar.
- Click `File > New > Display` and select Histogram Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Histogram Display.
---
# Loadmap
Pseudo‑3D heatmap of time spent in ranges of one parameter vs. another (e.g., gear vs. speed). Grid squares show in‑range value to nearest 1%; bucket counts control resolution. Refresh per lap in Live Mode.

## Adding a Loadmap Display
To add a Loadmap Display to a Page do one of the following:
- Click the Loadmap Display button on the DisplayToolbar.
- Click `File > New > Display` and select Loadmap Display.
- Press `Ctrl + Q` twice to use the QuickAccess Assistant and select NewLoadmap Display.
---
# Map
Satellite map centered on the current location (with zoom control and scale).

## Adding a Bing Map Display
To add a Bing Map Display to a Page do one of the following:
- Click the Bing Map Display button on the Display Toolbar.
- Click `File > New > Display` and select Bing Map Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Bing Map Display.
In the bottom right hand corner of the display is the scale. This changes when using zoom in and zoom out.
To zoom in and out of the display use the mouse wheel or press Ctrl + or Ctrl -.
## Parameter Selection
The Bing Map requires **Latitude** and **Longitude** parameters to be added to the display **respectively**.
To show the parameter selection dialog do one of the following:
- Press **P** in the Bing Map display.
- Right click the display and select **Parameter Selection**.
## Display Properties
To show the display properties do one of the following:
- Press **D** in the Bing Map display.
- Right click the display and select **Display Properties**.
**Note:** Clicking on a property provides a description of the property at the bottom of the tool window.

The options for the Bing Map Display are as follows:
| Group | Name | Description |
|-------------|-----------|-----------|
| General | Show Title Bar | Shows or hides the Display's title bar |
| General | Title | Title of the Display |
| Data | Auto Refresh Rate (Hz) | Sets the display updates rate (Hz) when automatically panning data. |
| Data | GPS Data Format | Format of GPS data in the session. It can be Decimal Degrees, F1MS, or Nascar. |
| Map | Lock Center to Data | Lock the center of the display to the current data location. |
---
# Notepad
Free text notes for checklists and session details; useful to park instructions alongside data.

## Adding a Notepad Display
To add a Notepad Display to a Page do one of the following:
- Click the Notepad Display button on the Display Toolbar.
- Click `File > New > Display` and select Notepad Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Notepad Display.
## Using the Notepad Display
The notepad display can be placed inside of another display's frame, in the legend area, or as a standalone display.
A Snapshot of the Notepad can be saved to a file. This can be saved as text or as an image.
1. Right click in the display.
2. Select either Snapshot to Data File or Snapshot to Image File.
A copy of the Notepad text can be saved to the Clipboard.
1. Right click in the display.
2. Select Copy to Clipboard.
Alternatively, press Ctrl + C to copy the Notepad text to the Clipboard.
---
# Numeric
!!! abstract "At a Glance"
**Parameters**: Up to 150
**Layout**: Auto-sizing grid
**Key Features**: Colour thresholds, hex formatting, status indicators
**Best For**: Dashboards, live monitoring, quick inspection
The Numeric Display shows instant numeric readouts for up to 150 parameters at the cursor position. Text auto-sizes to fit the display window, and colours can reflect warning/critical thresholds. Double-click a value to edit that parameter's properties.

## When to Use Numeric Display
:satellite: **Live monitoring**: Watch current values during recording
:bar_chart: **Dashboard creation**: Build custom parameter dashboards
:mag: **Quick inspection**: Check exact values at any cursor position
:traffic_light: **Status monitoring**: Use colour thresholds to highlight issues
:left_right_arrow: **Parameter comparison**: View multiple related parameters together
## Adding a Numeric Display
To add a Numeric Display to a page, choose one of the following methods:
- **Toolbar:** Click the **Numeric Display** button on the Display Toolbar.
- **Menu:** Go to **File > New > Display** and select **Numeric Display**.
- **Shortcut:** Press `Ctrl+Q` twice to open the Quick Access Assistant, type "Numeric", and select **New Numeric Display**.
Once added, use the **Parameter Browser** to add parameters and configure the display as needed.
## Display Anatomy
The Numeric Display shows a grid of parameters with:
- **Parameter name** (optional)
- **Current value** (at cursor position)
- **Units** (optional)
- **Colour highlighting** based on thresholds
Text size automatically adjusts to fit the available space.
## Key Features
### Auto-Sizing Layout
The display automatically:
- Calculates optimal text size based on window size
- Arranges parameters in a grid
- Adjusts when you resize the window
- Fills available space efficiently
You can override auto-sizing with fixed font size if preferred.
### Colour Thresholds
Parameters can show different colours based on their values:
!!! success "Normal"
Default text colour (typically white)
!!! warning "Warning"
Text colour changes when a value enters its warning range
!!! danger "Critical"
Uses critical colour (default red) for critical values
!!! info "Non-Critical"
If critical is disabled, non-critical values use the selected colour (default blue)
!!! note "Configuration"
Set warning and critical ranges for each parameter in the **Appearance** section of the Parameter Properties panel.
### Flexible Formatting
Control what's displayed for each parameter:
- Show/hide parameter name
- Show/hide description
- Show/hide numeric value
- Show/hide units
- Show/hide sign (+ or -)
- Show/hide status indicator
### Status Indicators
Parameters can display status symbols:
- **Up arrow**: Value increasing
- **Down arrow**: Value decreasing
- **Warning symbol**: In warning range
- **Critical symbol**: In critical range
### Hex Formatting
For parameters displayed in hexadecimal:
- Option to show "0x" prefix
- Configurable uppercase/lowercase
- Full hex formatting control
### Grid Overlay
Optional grid lines between parameters:
- Show/hide grid
- Custom grid colour
- Adjustable padding around items
- Column spacing control
## Display Properties
### Text Formatting
**Font Family**: Choose from available system fonts
**Font Size**:
- **Auto**: Automatically scales to fit window (recommended)
- **Fixed**: Specify exact point size
**Alignment**:
- Name alignment (Left, Center, Right)
- Value alignment (Left, Center, Right)
**Visibility**:
- Show parameter name
- Show parameter description
- Show value
- Show units
- Show sign (+ or -)
- Show status indicator
### Colour Options
**Text Colouring**:
- **Single colour for all**: All parameters use same text colour
- **Individual colours**: Each parameter uses its own colour
- **Apply critical/warning to text**: Threshold colours affect text colour
**Background Colouring**:
- **Display background**: Overall display background colour
- **Apply critical/warning to background**: Threshold colours affect background
- **Selected item colours**: Foreground and background for selected parameters
**Note**: Critical/warning colours can apply to text OR background, not both simultaneously.
### Grid and Layout
- **Show grid**: Enable/disable grid lines between parameters
- **Grid colour**: Colour of grid lines
- **Column padding**: Space between columns
- **Item padding**: Space around each parameter
### Data Update
- **Refresh rate**: Update frequency in Hz (1-1000 Hz)
- **Auto-refresh**: Enable continuous updates
## Adding Parameters
After creating a Numeric Display:
1. Open Parameter Browser (`Ctrl+P`)
2. Find the parameters you want to monitor
3. Drag parameters onto the display, or
4. Select parameters and Add to Display
You can add up to 150 parameters.
## Editing Parameter Properties
Double-click any parameter value to open its Parameter Properties panel where you can:
- Change parameter colour
- Set warning/critical thresholds
- Adjust decimal places
- Change display format (decimal, hex, scientific)
- Set custom units
- Enable/disable features per parameter
## Working with Parameters
### Selecting Parameters
- Click a parameter to select it
- Selected parameters show highlighted background
- `Ctrl+Click`: Add to selection
- `Shift+Click`: Select range
### Reordering Parameters
Drag parameters to reorder them within the grid.
### Removing Parameters
- Select parameter(s)
- Press `Delete` key, or
- Right-click > Remove Parameter
### Copying Values
**Copy to Clipboard**:
- Right-click > Copy (for selected parameters)
- Right-click > Copy All
Values copied as tab-delimited text, suitable for pasting into Excel or other tools.
### Snapshot Export
Export current display values to file:
1. Right-click display
2. Select "Snapshot to File"
3. Choose format and location
## Keyboard Shortcuts
| Key | Action |
|-----|--------|
| `D` | Display Properties |
| `Delete` | Remove selected parameters |
| `Ctrl+C` | Copy selected values |
| `Ctrl+A` | Select all parameters |
| `↑/↓/←/→` | Navigate selection |
## Example Configurations
=== "Dashboard Layout"
Create a clean monitoring dashboard:
- [x] Set **Show parameter name**: ON
- [x] Set **Show value**: ON
- [x] Set **Show units**: ON
- [ ] Set **Show description**: OFF
- [x] Enable **Apply critical/warning to text**
- [x] Set appropriate thresholds
:bar_chart: **Perfect for**: Live monitoring stations
=== "Minimal Value Display"
Show just the numbers:
- [ ] Set **Show parameter name**: OFF
- [x] Set **Show value**: ON
- [ ] Set **Show units**: OFF
- [x] Use **Individual colours** for differentiation
- [ ] Disable **Show status indicator**
- [ ] Hide grid for cleaner look
:1234: **Perfect for**: Dense parameter grids
=== "Status Monitor"
Highlight issues immediately:
- [x] Enable **Apply critical/warning to background**
- [x] Set **Display background**: Dark colour
- [x] Configure warning/critical thresholds
- [x] Enable **Show status indicator**
- [x] Use **Auto font size** for visibility
:traffic_light: **Perfect for**: Alert dashboards
## Tips & Tricks
!!! tip "Layout Optimization"
:white_check_mark: **Dashboard creation**: Use Numeric Display as main dashboard component
:art: **Colour coding**: Set up threshold colours to instantly spot issues
:arrows_counterclockwise: **Live monitoring**: Keep refresh rate reasonable (20-60 Hz) to avoid flicker
!!! tip "Data Display"
:1234: **Hex values**: Great for displaying status words and bit fields
:mag: **Quick check**: Add Numeric Display temporarily to inspect specific values
:desktop_computer: **Multi-monitor**: Float Numeric Display on second monitor for live monitoring
:bookmark_tabs: **Parameter grouping**: Group related parameters for easier monitoring
## Troubleshooting
??? question "Text too small to read?"
- Reduce number of parameters
- Increase window size
- Use fixed font size instead of auto
??? question "Text too large?"
- Add more parameters to fill space
- Use fixed font size and reduce point size
??? question "Colours not showing?"
- Check warning/critical thresholds are configured in Parameter Properties
- Verify "Apply critical/warning" option is enabled
- Check text vs background colour application setting
??? question "Values not updating?"
- Check refresh rate is appropriate
- Verify session is loaded and active
- Check cursor is moving (if not live)
??? question "Parameter disappeared?"
May have been deleted instead of hidden. Re-add from Parameter Browser.
---
# Dash
A simulator of the Motion Applied PCU Dash (as fitted to steering wheels). Supports multiple dash product types; auto‑loads a raw file if present (per Options). Positioning/alignment controls help fit the simulator to the display window.

## Adding a PCU Dash Display
To add a PCU Dash Display to a Page do one of the following:
- Click the PCU Dash Display button on the Display Toolbar.
- Click `File > New > Display` and select PCU Dash Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New PCU Dash Display.
---
# Scatterplot
!!! abstract "At a Glance"
**Parameters**: Up to 5 XYZ sets
**Modes**: 2D (XY) or 3D (XYZ with colour mapping)
**Key Features**: Best-fit lines, zoom box, colour mapping
**Best For**: Correlation analysis, efficiency maps, calibration maps
The Scatterplot is a two-dimensional (X-Y) plot of one parameter against another, optionally colour-mapped by a third Z parameter. It's designed to reveal relationships and trends across sessions, with controls for sampling density, draw style, best-fit curves, and engineering reference lines. Up to five parameter sets can be shown in one display.

## When to Use Scatterplot Display
:chart_with_upwards_trend: **Correlation analysis**: See how two parameters relate to each other
:world_map: **Map creation**: Create torque maps, efficiency maps, calibration maps
:mag: **Pattern identification**: Spot trends and clusters in data
:art: **Multi-parameter relationships**: Visualise three parameters simultaneously with colour mapping
:left_right_arrow: **Comparison**: Plot multiple parameter sets to compare behaviour
## Adding a Scatterplot Display
To add a Scatterplot Display to a page, use one of the following methods:
- **Toolbar:** Click the **Scatterplot Display** button on the Display Toolbar.
- **Menu:** Go to **File > New > Display** and select **Scatterplot Display**.
- **Shortcut:** Press `Ctrl+Q` twice to open the QuickAccess Assistant, type "Scatterplot", and select **New Scatterplot Display**.
- **From Waveform:** Select two parameters in a Waveform legend and use **View Scatterplot of Selected Parameters** (`Ctrl+T`) to create a Scatterplot pre-wired to those signals.
A third "Z" parameter can be selected to create a three-dimensional scatter plot.
### Adding the Z-axis
1. Press `P` on the display to open parameter configuration.
2. Click the **Use Z Axis** box.
3. Select the parameter from the list.
4. The Z-axis is scaled using a colour bar on the Scatterplot display.
## Display Anatomy
- **Plot Area**: Shows data points
- **X-Axis**: Horizontal axis (first selected parameter)
- **Y-Axis**: Vertical axis (second selected parameter)
- **Colour Bar**: Shows Z-axis mapping (if 3D mode)
- **Grid**: Optional grid overlay
- **Best-Fit Lines**: Optional trend lines
- **Zero Axes**: Optional reference lines at X=0 and Y=0
## Key Features
### 2D and 3D Plotting
**2D Mode (X vs Y)**:
- Plot one parameter against another
- Points coloured by parameter or fixed colour
- Simple correlation analysis
**3D Mode (X vs Y vs Z)**:
- Third parameter mapped to point colours
- Colour bar shows Z-value scale
- Visualise three dimensions simultaneously
### Multiple Parameter Sets
Add up to 5 different XY or XYZ parameter sets:
- Each set plots as separate series
- Different colours per set
- Compare different parameter relationships
- Independent best-fit lines per set
### Colour Mapping
When using Z-axis (3D mode):
- Points coloured by Z-value
- Colour bar shows value-to-colour mapping
- Customise colour scale
- Adjust colour range
### Draw Styles
Choose how data points appear:
- Points (dots)
- Lines connecting points
- Points with connecting lines
- Filled shapes
### Grid Configuration
**Grid Size Options**:
- Small: Fine grid for detailed work
- Medium: Balanced grid spacing
- Large: Coarse grid for overview
- Custom: Specify exact spacing
**Grid Display**:
- Show/hide major gridlines
- Show/hide minor gridlines
- Custom grid colours
- Adjust grid opacity
### Zoom and Navigation
**Zoom Box**:
- Click and drag to create zoom region
- Automatically zooms to selected area
- Undo/redo zoom with toolbar buttons
**Zoom History**:
- Multiple zoom levels remembered
- Navigate back/forward through zoom history
- Reset to full view
**Manual Scaling**:
- Set exact X and Y axis ranges
- Auto-scale to data
- Lock aspect ratio (optional)
### Cursor Modes
**Value Mode**: Standard cursor
**Crosshair Mode**: Adds horizontal and vertical reference lines
**In-Place Reference Line**: Fixed reference marker
## Best Fit & Reference Lines
### Opening the Editor
- Right-click the Scatterplot and choose **Edit Best Fit and Reference Lines...**.
- The editor lists all current lines with X/Y parameter binding, type (Best Fit or Reference), formula (for Reference Lines), and specified order (for Best Fit).
### Best Fit Lines
- Polynomial fit up to 5th order.
- **Order:**
- *Unspecified*: ATLAS automatically selects the most accurate polynomial order (up to 5).
- *Specified (1-5)*: Forces that exact order (e.g., 1 = linear).
- **Limits:** Define which samples are used for the fit (do not clip the drawn line). The calculated line spans the entire plot area.
- **Colour & Sessions:** Line colour defaults to the set's colour. In compare mode, each Best Fit line is recalculated per session and uses the session colour. Custom colours apply only in single-session mode.
**Fit Types Available:**
| Type | Use Case | Formula |
|------|----------|---------|
| Linear | Straight relationships | y = mx + b |
| Polynomial | Curved relationships | y = aₓxⁿ + ... + a₁x + a₀ |
| Power | Power law | y = axᵇ |
| Exponential | Growth/decay | y = aeᵇˣ |
| Logarithmic | Log relationships | y = a ln(x) + b |
!!! tip "Formula Display"
Enable **Show Formula** to display the equation with coefficients near the line. Updates when data changes!
### Reference Lines
- Explicit formula: Supply coefficients for `Y = f(X)`. Use **Auto Calculate** to fill coefficients from the current sample set.
- **Limits:** Define where the line is drawn (limits do clip the rendered extent).
- **Colour:** Reference line colour is retained across sessions — one line per scatterplot.
### Placing a Linear Reference Line (Interactive)
- Choose **Place Linear Reference Line** from the right-click menu.
- A temporary white line with drag handles appears:
- Drag centre to move; drag ends to pivot and stretch.
- Confirm to persist the line, then select which scatterplot set to apply it to.
- X/Y axis limits are inferred from handle positions. Changing the selected set updates coefficients and limits; manual tweaks are lost if you switch sets again.
### Line Lifecycle & Visibility
- **Automatic deletion:** Lines are tied to specific X/Y parameter pairs. Deleting X or Y, swapping axes, or replacing Z with X or Y deletes associated lines without warning. Undo does not restore them.
- **Global toggles:**
- *Show Best Fit and Reference Lines* (on/off for all lines).
- *Show Best Fit Line Formulas* (shows formulas under the X-axis).
- Per-line or per-set visibility toggles are not available.
!!! warning "Lines and Parameter Changes"
If lines disappear after changing parameters, remember that changing X/Y (or swapping with Z) auto-deletes associated lines. Recreate them after the change.
## Scatterplot Sampling Modes
In the ATLAS Scatterplot, there is a selection of different _Data Point Modes_.
The different _Data Point Mode_ selection alters the way in which the X, Y (and Z) samples are calculated for plotting co-ordinates on the scatterplot.
These can be accessed via the _Display Properties_ Window for the Scatterplot.

There are 6 different modes, each illustrated below with a worked example:
* All Samples
* Fixed Frequency
* Fixed Sample Count
* X Parameter
* Y Parameter
* Z Parameter
This mode setting applies at a _display_ level, so any plots within that display inherit these properties.
### All Samples Mode
_ATLAS 10.4.1 and later_

!!! note
In this mode, the _Frequency (Hz)_ and _Sample Count_ fields are ignored and read only.
_All Samples_ mode operates by taking each sample of the highest rate parameter, and referencing the sample and hold values of the other parameter(s). There is no averaging of samples, and only real values will be plotted.
If the X Parameter is logged at 100Hz, and the Y at 10Hz, the Y parameter will effectively be super-sampled at 100Hz in order to plot a point for each X parameter sample. If super-sampling is not desired, we recommend creating a function(s) which down-samples parameters where required, such that X, Y (and Z) are all at the same rate.
**Example**

| Time | X Parameter Value (Blue) 2Hz | Y Parameter Value (Red) 1Hz | X Co-ordinate plotted | Y Co-ordinate plotted |
| ----- | --------------------------------- | --------------------------------- | ------------------------- | ------------------------- |
| 0.0 | 0 | 4 | 0 | 4 |
| 0.5 | 1 | | 1 | 4 |
| 1.0 | 2 | 2 | 2 | 2 |
| 1.5 | 3 | | 3 | 2 |
| 2.0 | 4 | 0 | 4 | 0 |
| 2.5 | 5 | | 5 | 0 |
### X, Y, Z Parameter
_ATLAS 10.4.3 and later_
ATLAS 10.4.3 introduced 3 new modes in the scatterplot: X, Y and Z Parameter.
These work in a similar manner to _All Samples_ mode — however instead of inferring the highest rate parameter and using that to look up corresponding values on the other axes, the user can specify explicitly whether the X, Y or Z parameter is used as the "master".
**Example: X Parameter**
For every sample of the X Parameter, a corresponding value of Y (or Z) is referenced regardless of the rate of these parameters:

| Time | X Parameter Value (Blue) 2Hz | Y Parameter Value (Red) 1Hz | X Co-ordinate plotted | Y Co-ordinate plotted |
| ----- | --------------------------------- | --------------------------------- | ------------------------- | ------------------------- |
| 0.0 | 0 | 4 | 0 | 4 |
| 0.5 | 1 | | 1 | 4 |
| 1.0 | 2 | 2 | 2 | 2 |
| 1.5 | 3 | | 3 | 2 |
| 2.0 | 4 | 0 | 4 | 0 |
| 2.5 | 5 | | 5 | 0 |
**Example: Y Parameter**
For every sample of the Y Parameter, corresponding samples of X (or Z) are referenced:

| Time | X Parameter Value (Blue) 2Hz | Y Parameter Value (Red) 1Hz | X Co-ordinate plotted | Y Co-ordinate plotted |
| ----- | --------------------------------- | --------------------------------- | ------------------------- | ------------------------- |
| 0.0 | 0 | 4 | 0 | 4 |
| 0.5 | 1 | | | |
| 1.0 | 2 | 2 | 2 | 2 |
| 1.5 | 3 | | | |
| 2.0 | 4 | 0 | 4 | 0 |
| 2.5 | 5 | | | |
### Fixed Frequency and Fixed Sample Count Modes

_Fixed Frequency_ mode reads the _Frequency (Hz)_ field, but ignores _Sample Count_.

_Fixed Sample Count_ mode reads the _Sample Count_ field, but ignores _Frequency (Hz)_.
_Fixed Frequency_ & _Fixed Sample Count_ modes calculate samples to plot in a very similar way.
Both of these modes calculate a Time Period and then plot **averages** of X, Y or Z parameters over that Period.
* If a Period only spans a single sample, then the real sample value will be used;
* If the Period spans multiple samples, then those samples will be averaged.
The only difference between the modes is how the Time Period is calculated.
**Fixed Frequency Period Calculation**
Fixed Frequency Sample Time Period is set by a frequency.
_Time Period = 1/Frequency (Hz)_
If the Frequency is set to _0.25Hz_, then the Time period will be _4 seconds_ _(1/0.25)_.
**Fixed Sample Count Period Calculation**
Fixed Sample Count Time Period is set by splitting up the Display Time range, into a number of samples.
_Time Period = Display Time Range / Number of Samples_
If the Display Time range is displaying _20 seconds_ of data (can be changed by Zoom Level), and the Number of Samples is set to _5_, then the Time Period will be _4 seconds_ _(20/5)_.
**Example: Fixed Frequency & Fixed Sample Counts**

Time
X Parameter Value (Blue) 2Hz
Y Parameter Value (Red) 1Hz
X Co-ordinate plotted
Y Co-ordinate plotted
Sample Period 1 0-1.5 Seconds
0
4
(0+1+2) / 2 = 1.5
(4+2) / 2 = 3
1
2
2
Sample Period 2 1.5-3.0 Seconds
3
(3+4+5) / 2 = 6
0
4
0
5
In the example above, Sample Period of 1.5 seconds could be achieved in both _Fixed Frequency_ or _Fixed Sample Count_:
_Time Period (Fixed Frequency) = 1 / **0.667Hz**_
_Time Period (Number of Samples) = 6 (seconds on display) / **2 (samples)**_
## Display Properties
### Data Configuration
- Fixed frequency (Hz)
- Fixed sample count
- Data point mode (see [Sampling Modes](#scatterplot-sampling-modes))
- Show Z-axis colour mapping
### Grid Settings
- Grid size (Small/Medium/Large/Custom)
- Custom grid spacing
- Show major gridlines
- Show minor gridlines
- Grid colour
### Visual Options
- Primary draw style
- Show boundary lines (best-fit)
- Show zero axes
- Show best-fit formulas
- Show colour bar (3D mode)
- Background colour
### Axes
- X-axis label and range
- Y-axis label and range
- Z-axis label and range (3D)
- Auto-scale options
- Lock aspect ratio
## Working with Parameters
### Adding Parameter Sets
1. Add X-axis parameter (first)
2. Add Y-axis parameter (second)
3. (Optional) Add Z-axis parameter (third)
4. Repeat for additional parameter sets (up to 5)
### Editing Parameter Properties
Double-click axis label or parameter to configure:
- Parameter selection
- Colour assignment
- Scale and range
- Units display
- Decimal precision
### Removing Parameters
- Select parameter set
- Press `Delete` or right-click > Remove
## Keyboard Shortcuts
| Key | Action |
|-----|--------|
| `D` | Display Properties |
| `P` | Parameter configuration |
| `Z` | Zoom box mode |
| `Ctrl+Z` | Undo zoom |
| `Ctrl+Y` | Redo zoom |
| `Home` | Reset zoom |
| `Ctrl+T` | View Scatterplot of Selected Parameters (from Waveform) |
| `Delete` | Remove selected parameter set |
## Example Use Cases
=== "Torque Map"
Create an engine torque map:
1. Add Scatterplot Display
2. **X-axis**: Engine RPM
3. **Y-axis**: Throttle Position
4. **Z-axis**: Engine Torque (colour mapped)
5. Enable colour bar
6. Adjust grid for readability
7. Set appropriate axis ranges
:gear: **Result**: Visual map of torque across RPM and throttle
=== "Correlation Analysis"
Analyse parameter relationships:
1. Add parameters to analyse (X vs Y)
2. Add linear best-fit line
3. Enable "Show Formula"
4. Look for strong correlation (tight to line)
5. R² value indicates correlation strength
:mag: **Result**: Quantify relationship between parameters
=== "Efficiency Mapping"
Find efficient operating zones:
1. **X-axis**: Speed
2. **Y-axis**: Power
3. **Z-axis**: Fuel consumption (colour)
4. Identify efficient zones (cooler colours)
5. Spot inefficiencies (warmer colours)
:zap: **Result**: Optimise performance and efficiency
## Tips & Tricks
!!! tip "Getting Started"
:white_check_mark: **Start simple**: Begin with 2D, add Z-axis when needed
:grid: **Grid sizing**: Use Custom grid for specific map resolutions
:art: **Colour scales**: Adjust Z-axis range to enhance colour contrast
!!! tip "Analysis"
:mag: **Zoom in**: Work at appropriate detail level for analysis
:chart_with_upwards_trend: **Best-fit lines**: Use to quantify relationships numerically
:left_right_arrow: **Multiple sets**: Compare different sessions or laps
:floppy_disk: **Save templates**: Save scatterplot configurations for repeated use
!!! tip "Performance"
If the plot feels cluttered, reduce density via Fixed Sample Count or switch Draw Style to Small Point or Cross.
If Z-colouring appears sparse, check the Z limits (Parameter Properties > Appearance > Limits). Points with Z outside limits are not drawn.
To focus on part of the lap/run, set a Reference Cursor on a Waveform and use the Scatterplot's solid/faint point effect to isolate that window.
## Troubleshooting
??? question "No data points showing?"
- Check parameters are added correctly
- Verify session is loaded
- Check axis ranges include data
- Try auto-scale
??? question "Points too dense to see pattern?"
- Use fixed frequency mode to thin data
- Zoom into specific regions
- Adjust point draw style
- Enable best-fit line to see trend
??? question "Colour bar not showing?"
- Verify Z-axis parameter is added
- Check "Show colour bar" is enabled
- Check Z-parameter has valid data
??? question "Best-fit line incorrect?"
- Check fit type is appropriate for data
- Try different polynomial degree
- Verify sufficient data points
- Check for outliers affecting fit
??? question "Zoom stuck?"
- Press `Home` to reset zoom
- Use undo zoom (`Ctrl+Z`)
- Check manual axis ranges
??? question "Lines disappeared after parameter change?"
- Lines are tied to specific X/Y parameter pairs
- Deleting X or Y, swapping axes, or replacing Z with X or Y deletes associated lines without warning
- Undo does not restore them — recreate the lines after the change
---
# Summary
Lap‑based statistics for selected parameters as a table or as a plot. First columns are fixed: Lap #, Lap Name, Lap Time. For each parameter, you can add stats columns such as Min, Max, Mean, Start, End, Change, Range, Absolute Mean, Geometric Mean, Std Dev, Slope, Slope Intercept, R².

## Adding a Summary Display
To add a Summary Display to a page, use one of the following methods:
- Click the **Summary Display** button on the Display Toolbar.
- Go to **File > New > Display** and select **Summary Display**.
- Press **Ctrl + Q** twice to open the Quick Access Assistant, then select **New Summary Display**.
Once added, use the **Parameter Browser** to choose parameters and configure the display as needed.
The first three columns—**Lap #**, **Lap Name**, and **Lap Time**—are always shown. For each parameter, you can display one or more statistics over the relevant data range. Available statistics include:
- **Min**: The minimum value recorded for the parameter within the lap.
- **Max**: The maximum value recorded for the parameter within the lap.
- **Mean**: The arithmetic average of all parameter values within the lap.
- **Start**: The parameter value at the beginning of the lap.
- **End**: The parameter value at the end of the lap.
- **Change**: The difference between the end and start values of the parameter for the lap.
- **Range**: The difference between the maximum and minimum values for the parameter within the lap.
- **Absolute Mean**: The mean of the absolute values of the parameter within the lap.
- **Geometric Mean**: The geometric average of the parameter values within the lap.
- **Standard Deviation**: A measure of the variability or dispersion of the parameter values within the lap.
- **Slope**: The rate of change of the parameter values over the lap, calculated using linear regression.
- **Slope Intercept**: The intercept value from the linear regression of the parameter values over the lap.
- **Slope R Squared**: The coefficient of determination (R²) indicating how well the linear regression fits the parameter data within the lap.
You can resize columns individually, or right-click and select **Auto Resize Columns** to automatically adjust all column widths to fit the data.
To switch between table and plot views, right-click the display and select **Show As Plot** or **Show As DataGrid**.
---
# Surface Map
The Surface Map Display provides an interactive 3D visualization using a `.3d` map definition. It pairs two parameters (such as throttle and engine speed) and interpolates a third value. The display shows the mesh from the `.3d` file, data points colored by the X‑axis parameter, and highlights the current cursor point. You can rotate the map with the mouse, zoom with the mouse wheel, and double‑click to reset the view.

## Adding a Surface Map Display
To add a Surface Map Display to a page, use one of the following methods:
- Click the **Surface Map Display** button on the Display Toolbar.
- Go to **File > New > Display** and select **Surface Map Display**.
- Press **Ctrl + Q** twice to open the Quick Access Assistant and select **New Surface Map Display**.
## Setting Up the Display
After adding the display, specify the location of the `.3d` file:
1. Press **D** to open the Display Properties tool window.
2. Enter the file location in the **Map Definition** option.
Next, use the **Parameter Browser** to add the two parameters for which the map file is configured.
## Display Features
- The map (grid and mesh) appears once parameters are set.
- The mesh (from the `.3d` file) is shown in white by default.
- Data points are colored according to the X-axis parameter (blue in the example).
- The current cursor point is highlighted as an enlarged point (red in the example).
- All display properties can be adjusted in the Display Properties tool window.
You can interact with the map by rotating it with the mouse, zooming in or out with the mouse wheel, and resetting its position by double-clicking the display.
---
# Video
!!! danger "Preview Functionality"
Video display is currently a preview feature. As such, the content in this page is subject to change based on feedback and roadmap changes.
# Video Display
Related video (e.g., in‑car camera) played alongside session data.

## Adding a Video Display
!!! note
You must enable preview features in Tools > Options > General > Preview Features to use the Video Display.
To add a Video Display to a page, use one of the following methods:
- **Display Toolbar:** Click the **Video Display** button.
- **Menu:** Go to **File > New > Display** and select **Video Display**.
- **Quick Access Assistant:** Press `Ctrl + Q` twice, then select **New Video Display**.
## Synchronising Video with a Session
To synchronise a video with session data:
- **Play Video:** Click **Play** on the video. The waveform cursor will automatically synchronise to the current video frame.
- **Navigate by Cursor:** If the video is stopped, click on the waveform cursor. The video will display the frame corresponding to the timestamp under the cursor.
---
# Waveform
!!! abstract "At a Glance"
**Parameters**: Unlimited
**X-Axis**: Time or Distance
**Key Features**: Multiple cursors, statistics, events, zoom
**Best For**: Time-series analysis, multi-session comparison
The Waveform Display plots multiple parameters as traces against time or distance. It's the most versatile display in ATLAS, supporting live telemetry and historical sessions, fast zooming, and rich formatting. Use it for:
- Braking/throttle application vs. speed, per corner or lap
- Multi-session comparisons with Time Difference (TDiff) in Distance mode
- Event-driven triage (ECU events/errors) aligned to timestamps or distances

## When to Use Waveform Display
:racing_car: **Driver analysis**: Brake/throttle application vs. speed per corner
:bar_chart: **Multi-session comparison**: Compare different laps or sessions side-by-side
:mag: **Event investigation**: See telemetry context around ECU events
:chart_with_upwards_trend: **Trend analysis**: Identify patterns over time or distance
:satellite: **Live monitoring**: Watch real-time telemetry streams
## Adding a Waveform Display
=== "Quick Access"
Press `Ctrl+Q` twice, type "Waveform", press `Enter`
:zap: **Fastest method**
=== "Toolbar"
Click the Waveform icon on the Display Toolbar
:mouse: **One click** when you know the icon
=== "Menu"
**File** > **New** > **Display** > **Waveform Display**
:books: **Browse all options**
### Parameter Selection
- Use Parameter Browser (default max 100 parameters, configurable)
- Double-click legend items for Parameter Properties (supports single/multi-session editing)
### Compare Sets
- Load multiple sessions into a set
- Switch sets: `Shift+` (selected display), `Ctrl+` (whole page), or click coloured tag on title bar
## Display Anatomy
### Plot Area
- One coloured trace per parameter
- Grid (vertical/horizontal/both) with adjustable spacing (shown at top of plot)
- Cursor line showing current position
- Cursor text at top-left (shows Time, and Distance in Distance mode)
- X-axis showing time or distance
- Event markers below X-axis (coloured squares)
### Legend
- One row per parameter with cursor value and statistics
- Colour bar matches trace colour
- Click rows to select parameters
- Reposition, resize, grid, show units, toggle headers
- Select rows (`Ctrl`/`Shift`) to highlight traces and perform actions (hide/delete/distribute)
### Axes
- **X-Axis**: Time (default) or Distance (press `K` to switch)
- **Y-Axis**: Per-parameter scales (enable in Parameter Properties)
## Key Features
### Cursors
**Cursor Modes** (View menu or shortcuts):
| Mode | Key | Description |
|------|-----|-------------|
| Value | `V` | Vertical line, shows sample values (default) |
| Crosshair | `C` | Adds horizontal sight line |
| Gradient | `G` | Diagonal line with three handles; legend shows per-signal gradient |
| Hide | `N` | Turn off cursor display |
!!! tip "Reference Cursor"
Press `R` to add a red reference line for comparison.
**Features:**
- Red reference line; grey window between reference and current cursor defines analysis range
- Legend shows ΔTime/ΔDistance and computes statistics for that window
- Drag either cursor to adjust window size

### Statistics
Enable statistics to see parameter behaviour over ranges:
!!! note "Setup Steps"
1. Check **Show Statistics** in Display Properties
2. Choose your **Statistics Level**
3. Toggle metrics with keyboard shortcuts
**Statistics Levels:**
| Level | Scope | Prefix |
|-------|-------|--------|
| Display | Visible timebase | D |
| Lap | Current lap only | L |
| Session | Entire session | S |
| All | All loaded sessions | A |
Reference Cursor can have its own level or swap with the chosen level.
**Available Metrics:**
| Metric | Key | Description |
|--------|-----|-------------|
| Min | `M` | Minimum value |
| Max | `X` | Maximum value |
| Mean | `N` | Average value |
| Delta | `E` | Difference between cursors |
| Std Dev | `Q` | Standard deviation |
!!! example "Reading Statistics"
Statistics appear in legend with prefixes: **LMin** (Lap Min), **SMax** (Session Max), etc.
### Selecting, Highlighting, Hiding Parameters
**Select Parameters**:
- Click legend row to select one parameter
- `Ctrl+Click`: Add to selection
- `Shift+Click`: Select range
- Selected traces flash (by default)
**Hide Selected Parameters**:
- Hides traces but keeps legend entries
- Names shown with strikethrough
- Values shown in italics
- Unhide by selecting and pressing Hide again
**Delete Selected Parameters**:
- Removes parameters completely from display
**Distribute**:
- Stacks selected traces into separate bands
- Useful for avoiding overlapping traces
- **Reset Distribute**: Returns to normal view
**Autoscale**:
- Fits selected parameters to available vertical space
- **Reset Auto-Scale**: Returns to original scaling
### Events and Markers
**Event Indicators:**
!!! info "Event Colours"
Coloured squares below X-axis indicate event severity:
- :red_square: **Red**: High priority events
- :blue_square: **Blue**: Medium priority events
- :green_square: **Green**: Low priority events
**Features:**
- Hover for event details
- Multiple events at same position show highest priority colour
- Mask/unmask events by hovering and right-clicking
- View masked events via context menu
**Other Markers:**
| Marker Type | Description | Toggle |
|-------------|-------------|--------|
| Lap Markers | Vertical dashed lines at lap boundaries | Display Properties |
| Date/Time Markers | Clock time or lap time on X-axis | Time mode only |
| Circuit Stripe | Track sectors/segments across top of plot; toggle labels; choose global/overridden Circuit Definition | Display Properties |
### Zoom and Navigation
**Zoom Box**:
- Click and drag to create zoom region
- Top-to-bottom: Zoom X and Y axes
- Bottom-to-top: Zoom X-axis only (zoom strip)
- Mouse wheel: Zoom X-axis (time/distance)
- Toolbar zoom buttons
**Autoscroll** (Live Sessions):
- Middle mouse button (or both buttons)
- Pointer position controls scroll speed
- Click to exit autoscroll mode
**Pause/Inspect**:
- Single-click plot to pause scrolling and position cursor
- Double-click to resume scrolling
### Time vs. Distance Mode
Press `K` to cycle between X-axis mappings:
- **Time Mode**: X-axis shows elapsed time
- **Distance Mode**: X-axis shows distance travelled
**Time Difference (TDiff)** in Distance Mode:
- Plots time difference between sessions
- Shows which session is ahead/behind at each distance
- Enable **Show Time Diff** in Display Properties
- Choose TDiff start point:
- Start of lap
- Current cursor position
### Sampling and Interpolation
**Sub-Sampling** (when cursor spans multiple samples):
Choose how to display data:
- **First**: Show first sample value
- **Min**: Show minimum in range
- **Max**: Show maximum in range
- **Mean**: Show average
- **Min→Max**: Draw vertical line from min to max
- **Max→Min**: Draw vertical line from max to min
Legend shows min/max values; trace shows vertical min-max line.
**Interpolation**:
- Enable **Interpolate between samples** (Parameter Properties > Post Processing) to smooth traces and generate interpolated legend values
- Makes stepped traces appear smoother
### Session Comparison
**Show Differences**:
- Displays value difference between sessions at cursor
- Enable in Parameter Properties > Post Processing
- Pause live scrolling for readability
- Not available for:
- Boolean or Text parameters
- Functions
- When using Filters or Trends
### Left-to-Right Mode (Strip Chart)
For live telemetry analysis:
1. Enable **Draw left to right** in Display Properties
2. Traces overwrite from left as laps progress
3. Set **Gap %** to add gap ahead of cursor
4. Choose **Left to Right Overlay** lap for reference
Useful for comparing current lap against previous laps in real-time.
### Live Telemetry & Historical Replay
- **Live:** Waveform scrolls/updates if a live session is in the set
- **Historical Replay:** Enable **Allow Historical Replay**; double-click plot to replay
## Keyboard Shortcuts
### Cursor Modes
| Key | Action |
|-----|--------|
| `V` | Value cursor mode |
| `C` | Crosshair cursor mode |
| `G` | Gradient cursor mode |
| `N` | Hide cursor |
| `R` | Toggle reference cursor |
### Statistics
| Key | Action |
|-----|--------|
| `M` | Toggle Min statistic |
| `X` | Toggle Max statistic |
| `N` | Toggle Mean statistic |
| `E` | Toggle Delta statistic |
| `Q` | Toggle Std Dev statistic |
### Navigation
| Key | Action |
|-----|--------|
| `K` | Cycle X-axis mode (Time/Distance) |
| `D` | Display Properties |
| `←` / `→` | Move cursor |
| `Shift+←` / `Shift+→` | Move cursor faster |
| `Home` | Cursor to start |
| `End` | Cursor to end |
### Compare Sets
| Key | Action |
|-----|--------|
| `Shift+` | Switch set (selected display) |
| `Ctrl+` | Switch set (whole page) |
## Display Properties
Key properties you can configure:
### General
- Background colour
- Show grid (horizontal, vertical, both)
- Grid spacing
- Show title bar
- Allow historical replay
### Legend
- Position (top, bottom, left, right)
- Font size
- Show units
- Show warning indicators
- Value alignment
### Cursor & Statistics
- Cursor mode (Value, Crosshair, Gradient)
- Show statistics
- Statistics level
- Reference cursor level
### Time/Distance
- X-axis mode
- Show time difference
- TDiff start point
- Time notation format
### Events
- Show event indicators
- Show lap markers
- Show date/time markers
- Circuit stripe visibility
### Sub-Sampling
- Drawing mode (First, Min, Max, Mean, etc.)
- Interpolate between samples
## Example Configurations
=== "Driver Analysis"
Analyse brake/throttle inputs:
1. Add Waveform Display
2. Add Brake, Throttle, Speed parameters
3. Use **Distribute** to stack traces
4. Switch to **Distance** mode (`K`)
5. Add **Reference Cursor** (`R`) to compare corners
:racing_car: **Perfect for**: Corner-by-corner driver analysis
=== "Multi-Session Comparison"
Compare laps side-by-side:
1. Load multiple sessions
2. Switch to **Distance** mode (`K`)
3. Enable **Show Time Diff**
4. Use **Show Differences** for value deltas
:bar_chart: **Perfect for**: Lap comparison and performance progression
=== "Live Monitoring"
Real-time telemetry view:
1. Connect live session
2. Enable **Draw left to right** (strip chart mode)
3. Set **Gap %** ahead of cursor
4. Choose overlay lap for reference
:satellite: **Perfect for**: Pit wall and live engineering
## Tips & Tricks
!!! tip "Parameter Management"
:heavy_check_mark: **Too many parameters?** Use Distribute to stack traces vertically
:mag_right: **Can't see parameter?** Use Autoscale to fit to screen
!!! tip "Analysis"
:left_right_arrow: **Comparing laps?** Use Reference Cursor to compare two points
:triangular_flag_on_post: **Analysing events?** Event markers show when things happened
!!! tip "Visualisation"
:chart_with_upwards_trend: **Stepped signals?** Enable interpolation for smoother traces
:mag: **Large dataset?** Zoom in to see detail, zoom out for overview
:arrows_counterclockwise: **Multi-session comparison?** Use Time Diff in Distance mode
:world_map: **Track context?** Enable Circuit Stripe to see where on track
## Troubleshooting
??? question "No Y-axis scales showing?"
Enable per-parameter Y-Scale in Parameter Properties.
??? question "Traces overlapping and hard to read?"
- Use Distribute function to stack traces into bands
- Reduce number of visible parameters
- Hide less important parameters temporarily
- Use Autoscale to fit data to vertical space
??? question "Event markers not showing?"
- Check **Show Event Indicators** is enabled in Display Properties
- Verify events aren't masked in Event Filter Display
- Check event priorities are visible
??? question "Differences not showing?"
"Show Differences" not available with:
- Filters, Trends, or Functions
- Boolean/Text parameters
- During live scrolling (pause to read values)
??? question "Cursor not moving?"
- Click to focus the waveform display
- Check keyboard focus is on the display
??? question "Stepped signals look wrong?"
Consider enabling **Interpolate between samples** in Parameter Properties > Post Processing if interpolation is appropriate for the signal type.
??? question "Missing event markers?"
Ensure **Show Event Indicators** is on; check Event Filters for masked priorities.
---
# Web Display
An embedded browser—useful for live camera feeds, weather, or other web‑based information.

## Adding a Web Browser Display
To add a Web Browser Display to a Page do one of the following:
- Click the Web Browser Display button on the Display Toolbar.
- Click `File > New > Display` and select Web Browser Display.
- Press `Ctrl + Q` twice to use the Quick Access Assistant and select New Web Browser Display.
---
# Overview
Extend ATLAS capabilities by connecting with third‑party systems and custom workflows.
## [Remote Telemetry Architecture (RTA)](rta/index.md)
RTA provides low‑latency access to live and historical telemetry using your existing databases. It’s designed for teams building integrated data pipelines without complex setup.
### Key Functionality
- Database integration
- Live & historical session access
- OAuth2.0 with MFA
- Microservice‑based data delivery
## [APIs](apis/index.md)
ATLAS APIs provide direct programmatic access for automation, custom tooling, and deeper analysis.
**Includes:**
- SQL Race API — query and analyse telemetry datasets
- Automation API — streamline repetitive or operational tasks
- Display API — create specialised custom visual displays
---
# Overview
!!! danger "Prototype Functionality"
RTA was released as prototype functionality. As such, the content in these pages is subject to change based on feedback and roadmap changes.
# Introduction to RTA
ATLAS _Remote Telemetry Architecture_ (RTA) defines web services to let you load telemetry directly from your existing storage:
This can work with a wide range of technologies, such as:
* [InfluxDB](https://www.influxdata.com/products/influxdb/), [TimescaleDB](https://www.timescale.com/) and other time-series stores
* [MongoDB](https://www.mongodb.com/), [Couchbase](https://www.couchbase.com/) and other document databases
* [Parquet](https://parquet.apache.org/), [HDF5](https://www.hdfgroup.org/solutions/hdf5/) and other file formats
* [SQL Server](https://www.microsoft.com/en-gb/sql-server), [PostgreSQL](https://www.postgresql.org/), [MySQL](https://www.mysql.com/)...
## Live Monitoring
The RTA specification includes [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) streaming for live telemetry monitoring.
Our reference architecture recommends implementing this by taking a feed from your acquisition pipeline, and buffering it through [Redis](https://redis.io/) — which decouples the client activity and allows users to join the session at any point.
This enables ATLAS to display data in real-time even if your acquisition pipeline cannot write to storage in real-time, or if the storage is not available until acquisition is complete — common with file formats.
When users open live sessions, ATLAS selectively subscribes to the parameters on display using a [WebSocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) connection, and the [Redis](https://redis.io/) buffer covers the gap until data is flushed to storage. Users can get a complete and real-time view of the data even when joining hours into a session.
## Toolkit Services
The [RTA API Specification](../../../developer-resources/rta/api/index.md) provides all the nececessary information to create a slick integration between ATLAS and your data infrastructure, with detail including:
* [OpenAPI schema](https://www.openapis.org/faq) describing the REST API
* [JSON schemas](https://json-schema.org/) for the data model and query dialect
* [Protobuf schemas](https://developers.google.com/protocol-buffers) for low-level data transport
However, you can save a lot of development effort by deploying [services](../../../developer-resources/rta/services/index.md) from our implementation toolkit.
By using these services to cover all the data management functionality, you won't need to implement any of the browsing, search or configuration management features. All you'll need to write is a simple hook into your ingest pipeline, and a [Data Adapter Service](introduction/data-services.md):
These Toolkit Services provide [gRPC](https://grpc.io/) services for integration with the rest of your data infrastructure.
[gRPC](https://grpc.io/) is a modern, high performance framework for making service calls. It supports all popular programming languages, and the services are fully-described with schemas — so you get a high-quality client library that will work with your existing software stack, and high-quality developer tools to guide use of the API.
You can deploy these services on [Windows](../../../developer-resources/rta/downloads.md#binaries) or [Linux](../../../developer-resources/rta/downloads.md#binaries), and on-premises or in the Cloud using our [Docker images](../../../developer-resources/rta/downloads.md#docker). Our services are specifically designed to work well with [Kubernetes](https://kubernetes.io/) and [AWS](https://aws.amazon.com/).
## Standalone Options
If you do not have any central telemetry database or file archive, RTA may not be the right architecture for you — but ATLAS is also very capable operating standalone:
* ATLAS can browse and mount files directly.
This is a great option if your use case involves a lot of travel and in-field laptops.
* ATLAS can display and record live telemetry directly from equipment — e.g. CAN bus — or the local network.
This option is popular in motorsport and eSports.
Some plugin development will be required for both these capabilities.
[Contact us](mailto:sales@motionapplied.com) for a more in-depth technical discussion.
---
# Architectures
!!! danger "Prototype Functionality"
RTA was released as prototype functionality. As such, the content in these pages is subject to change based on feedback and roadmap changes.
# Architecture Patterns
The [RTA API Specification](../../../../developer-resources/rta/api/index.md) does not require any specific architecture or technology stack — but there are some common patterns.
This page illustrates some architectures supported by [services from our implementation toolkit](../../../../developer-resources/rta/services/index.md).
!!! info "Legend"
## Development
### RTA Server
[RTA Server](../../../../developer-resources/rta/services/rta-server/README.md) provides a simple, single-process deployment to experiment to explore the [RTA API Specification](../../../../developer-resources/rta/api/index.md) and gain familiarity with [Sessions](sessions.md), [Configuration](configuration.md) and the data types.
### Microservices
The [Toolkit Services](../../../../developer-resources/rta/services/index.md) are designed be to run as microservices within a [container orchestrator](https://docs.docker.com/get-started/orchestration/), like [Kubernetes](https://kubernetes.io/).
Here is the same capability, split into individual components:
All these services are horizontally-scalable, facilitating high-availability deployments.
### OAuth 2.0 Security
ATLAS and the [Toolkit Services](../../../../developer-resources/rta/services/index.md) can use [OAuth 2.0](https://oauth.net/2/) with multi-factor authentication:
The [Gateway Service](../../../../developer-resources/rta/services/rta-gatewaysvc/README.md) proxies the authorization bearer token through to the other microservices.
## Data Adapter Service
RTA does not require data format-shifting.
Instead of copying the data with a loader, you can index it in place and deploy a [Data Adapter Service](data-services.md) to read the store:
=== "InfluxDB"
_McLaren provide an [InfluxDB Data Service](../../../../developer-resources/rta/services/rta-influxdatasvc/README.md) in the implementation toolkit:_
=== "Files"
_Custom file formats can be served using exactly the same pattern:_
=== "Data Federation"
_Hetrogeneous formats can all be handled in one deployment:_
## Continuous Ingest and Live Streaming
The diagrams above show data being indexed after it has arrived. But this can be integrated into existing ingest pipelines.
Calls to the [Toolkit Services](../../../../developer-resources/rta/services/index.md) are made using [gRPC](https://grpc.io/), which is supported in a wide range of languages — so it is easy to publish [configuration](configuration.md) and [session](sessions.md) metadata from an existing framework.
This is not limited to metadata. You can live-stream data to ATLAS:
=== "Live Streaming"
_A copy of the data is streamed across to [Redis](https://redis.io/), and connected to clients via [Stream Service](../../../../developer-resources/rta/services/rta-streamsvc/README.md) web sockets:_
=== "Live Streaming with Files"
_This streaming strategy can provide a fast bypass when the store has high latency — for example, file storage:_
## Remote Access
The web services are specifically designed for high-latency operation across the WAN or Internet.
=== "Remote Access"
_Connections are secured with TLS and OAuth 2.0, so users can connect to a data center or cloud deployment without a VPN:_
=== "Remote Access across Company Boundaries"
_Many OAuth 2.0 providers offer identity federation, so subsets of data can be shared securely across company boundaries:_
---
# Data Services
!!! danger "Prototype Functionality"
RTA was released as prototype functionality. As such, the content in these pages is subject to change based on feedback and roadmap changes.
# Data Services
Data Services read samples and events from a telemetry store, and serve them to ATLAS.
The telemetry store could be a database, or a data lake, or an object store, or a set of files...
The service itself can be a simple read-only _data adapter_. It can extend an existing application, or it could be a standalone service sharing the existing data store. For high performance, it should access the data store as directly as possible rather than proxying a web service.
[Services from the toolkit](../../../../developer-resources/rta/services/index.md) can cover the other key requirements, which are:
* Data management — _[Sessions](sessions.md)_
* Describing the data model — _[Configuration](configuration.md)_
_Example deployment, with supporting [Gateway Service](../../../../developer-resources/rta/services/rta-gatewaysvc/README.md) (proxy) and [Schema Mapping Service](../../../../developer-resources/rta/services/rta-schemamappingsvc/README.md):_
The [Developer Guide](../../../../developer-resources/rta/worked-guide/index.md) includes a walkthrough demonstrating the process of [writing a Data Adapter Service](../../../../developer-resources/rta/worked-guide/tutorials/data-adapter/index.md), which can be written from scratch in any framework using the [API Specification](../../../../developer-resources/r../../../developer-resources/rta/api/index.md), or built in [ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core) taking advantage of Motion Applied's [library support](../../../../developer-resources/rta/downloads.md).
Development time can be as little as a few hours for a prototype, up to a few weeks for an efficient, production-grade service.
## Toolkit Services
Motion Applied currently provide two data services in the [services toolkit](../../../../developer-resources/rta/services/index.md):
[RTA Data Service](../../../../developer-resources/rta/services/rta-datasvc/README.md)
: Read/write storage optimized for RTA, backed by either a file system, or [Amazon S3](https://aws.amazon.com/s3/) and [DynamoDB](https://aws.amazon.com/dynamodb/).
Cost-efficient and very fast — but provides no data query or summarization capabilities.
[Influx Data Service](../../../../developer-resources/rta/services/rta-influxdatasvc/README.md)
: Data Adapter Service for [InfluxDB](https://www.influxdata.com/products/influxdb/).
---
# Sessions
!!! danger "Prototype Functionality"
RTA was released as prototype functionality. As such, the content in these pages is subject to change based on feedback and roadmap changes.
# Sessions
_Sessions_ are a logical way to organise telemetry — like a file system.
Each session is labelled with user-defined metadata, including:
* unique identity — GUID, database key, or query string
* human-readable name and properties
* timestamp and start/end time of the data
* relationships to other sessions
## Browse and Search
ATLAS leverages this metadata to make sessions easy to browse, filter and sort.
This system provides excellent scalability and can be tightly integrated with the existing data environment.
## Modelling and Simulation
ATLAS provides traceability and version control features to support _Virtual Product Development_ through models and simulations.
!!! example
Models are used extensively in _Formula One_ development. For example, an aerodynamics model predicts the air-flow over the car as it races around a track, depending on hundreds of variables — such as the ride height, wing angle and cooling setup.
On-track, air-pressure sensors and pitot tubes measure real downforce, and engineers use ATLAS to compare this telemetry with predicated parameters to find the correlation with the model. Both the telemetry and models may go through multiple versions to cleanup the data — for example, removing pressure traces from sensors that are contaminated with debris.
Simulated telemetry sessions are often used to add new parameters based on a physics model, signal processing pipeline, or machine learning algorithm. RTA can describe the relationship between the parent telemetry and child models — and ATLAS will leverage this to keep the data together.
## Alternate Versions
You can also offer users multiple versions of data.
For example, data collected during a test session might need some trimming and cleanup. ATLAS lets you switch out the original data for the clean version — yet keep the original available for easy reference.
## Applying this concept to your environment
Sessions typically represent a source of data — such as a set of equipment — and cover a bounded time period:
* If you are using ATLAS to monitor hardware and embedded systems, this may naturally encompass a test session.
* If you are integrating with a continuously-stored time series, you'll need to find a logical split.
For example, if you were collecting vehicle telemetry, you might define a session for each vehicle and journey.
You can build this catalogue in real-time, or as a batch process.
Here are a few example scenarios:
=== "Files"
_If you have an existing collection of telemetry files:_
* Map each file to a session, using the file name and metadata
* If several files belong together, you can treat them as one session — or use a parent-child relationship
=== "Databases"
_If you are using a time-series database like [InfluxDB](https://www.influxdata.com/products/influxdb/) or [TimescaleDB](https://www.timescale.com/):_
* Use the database tagging and query facilities
* Split the sessions are points of interest, or by schedule
=== "UDP Stream"
_If you are acquiring data from a real-time UDP stream:_
* You can open a session even before data starts flowing
* Metadata can be updated as you go — or later, to reflect test results
=== "Models"
_If you are processing each telemetry session through models:_
* You can associate the sessions in ATLAS so the data is loaded together
* Use the _type_, _quality_, _group_ and _version_ metadata to organise the model output
---
# Configuration
!!! danger "Prototype Functionality"
RTA was released as prototype functionality. As such, the content in these pages is subject to change based on feedback and roadmap changes.
# Configuration
ATLAS is data-driven: it uses _Configuration_ to describe the telemetry.
The core data types are:
* _Parameters_ — representing sampled data points, each with a time and value
* _Events_ — representing a moment in time, with associated text or values
Most time-series databases can do these, too — but ATLAS has some additional capabilities built from its heritage in Engineering, rather than infrastructure monitoring.
## Designed for Scale
ATLAS is designed for large sets of parameters, and many samples.
A typical session from a [Motion Applied TAG-320B ECU](https://motionapplied.com/products/TAG-320B) on a Formula One car contains 50,000 - 60,000 parameters. Of these, around 4,000 are sampled at up to 1 KHz, with the remainder being densely-packed snapshots of embedded memory captured every few seconds.
A race-length session contains about 2,000,000,000 samples.
## Apps and Parameter Trees
ATLAS is designed so that a stream of telemetry might contain data from multiple devices and models, assembled by different teams — so configuration is divided into _Apps_.
Each App can have 10,000+ parameters, so they are organised into a tree, which users can browse and search:
Parameters aren't just a name — they have descriptions, units, formatting and expected ranges.
## Calibration and Conversions
ATLAS can apply gain and offset calculations to correct parameter data.
This is useful when working with electronics and embedded systems.
The list of parameters and their valid ranges will be known when software is flashed onto a unit, but it may be necessary to zero some sensor readings after startup.
## Dense Data
ATLAS and RTA can handle data efficiently, by preserving the data width — from single-byte to double-precision.
There is also a facility to take a buffer — representing a section of memory from an embedded controller — and pick it apart into parameters. This is called _Row Data_ in the [API Specification](../../../../developer-resources/r../../../developer-resources/rta/api/index.md).
## Text
As in [Grafana](https://grafana.com/), parameters that represent enumerations can be mapped onto text.
Events can also carry text — or values that can then be formatted to text.
!!! note
ATLAS is not a logging platform: it is designed primarily for numerical telemetry.
Think [Prometheus](https://prometheus.io/), not [Fluentd](https://www.fluentd.org/).
---
# Overview
ATLAS APIs are designed with an API-first strategy, enabling seamless integration with third-party tools and cloud-native platforms. ATLAS APIs are a suite of extensibility interfaces designed to integrate, automate, and extend the capabilities of the ATLAS telemetry and data analytics platform. They support real-time and historical data workflows across motorsport, automotive, aerospace, and simulation environments.
## Key APIs and Usage
#### [SQLRace API](../../../developer-resources/atlas/sql-race/index.md)
Provides direct access to telemetry databases. Used for in-process data extraction and session creation.
#### [Display API](../../../developer-resources/atlas/display-api/index.md)
Enables creation of custom visualisations with native ATLAS look and feel.
#### [Stream API](../../../developer-resources/secu4/stream_api/index.md)
Built on gRPC and Protobuf for real-time telemetry streaming. Supports both reading and writing of telemetry packets.
#### [Configuration API](../../../developer-resources/system-monitor/configuration_api/index.md)
The Configuration API offers a cross-platform gRPC interface for ECU programming and monitoring, supporting integration with clients in multiple languages.
---
# Overview
Welcome to the Developer Resources section! This area provides everything you need to get started and succeed when integrating with the ATLAS platform. Here you'll find:
- **Getting Started Guides:** Step-by-step instructions for setting up your development environment.
- **Tools & Utilities:** Recommended tools and extensions to streamline your workflow.
- **Best Practices:** Coding standards, review guidelines, and tips for effective collaboration.
- **Reference Materials:** API documentation, architecture overviews, and troubleshooting resources.
## Developer Community
Looking for community examples and projects? Check out the [ATLAS Developer Community](https://github.com/atlas-dev-hub) on GitHub. This is the home for community-contributed examples, custom implementations, and collaborative projects that utilize our APIs. Whether you're building a custom dashboard, creating a new tool, or sharing insights, the Developer Community is the place to showcase your work and connect with other developers.
For official documentation and curated examples, you're in the right place. For open source products like the Stream API and Protocol definitions, visit [Software Products](https://github.com/Software-Products).
## API Areas
- :material-package-variant: __[NuGet Packages](./atlas/nuget/index.md)__
---
Access all McLaren API packages from the GitHub packages feed, covering data, display, RTA, and streaming.
- :material-database: __[SQL Race API](./atlas/sql-race/index.md)__
---
Read, write and record telemetry data using ATLAS's core data layer — sessions, parameters, laps and events.
- :material-robot: __[Automation API](./atlas/automation-api/index.md)__
---
Automate ATLAS workflows: session loading, workbook generation, display configuration, and data access.
- :material-monitor-dashboard: __[Display API](./atlas/display-api/index.md)__
---
Build custom display plugins that integrate natively with ATLAS, with full access to session and parameter data.
- :material-transit-connection: __[Bridge Service](./secu4/bridge_service/index.md)__
---
Decode raw ADS streams and convert telemetry to engineering values via the Stream Protocol.
- :material-library: __[Support Library](./secu4/support_library/index.md)__
---
Streaming support library for the MA DataPlatforms ecosystem.
- :material-file-search: __[Indexing Services](./secu4/indexing_services/index.md)__
---
Microservice solution for file and configuration indexing across the data platform.
- :material-swap-horizontal: __[Stream API](./secu4/stream_api/index.md)__
---
gRPC-based interface for real-time data streaming to and from Kafka brokers as part of the Open Streaming Architecture.
- :material-cog: __[Configuration API](./system-monitor/configuration_api/index.md)__
---
Multi-platform gRPC API for ECU programming and monitoring — supports C#, C++, Python, Java, and Go.
- :material-application-cog: __[System Monitor ActiveX](./system-monitor/active-x/index.md)__
---
OLE Automation interface for controlling System Monitor and requesting information from external applications.
- :material-cloud-sync: __[RTA](./rta/worked-guide/index.md)__
---
Remote Telemetry Architecture — API and toolkit services for integrating ATLAS with existing environments over gRPC.
Explore the topics in this section to accelerate your development.
---
# Overview
McLaren NuGet libraries are available from our [GitHub packages feed](https://github.com/orgs/mat-docs/packages?repo_name=packages).
A free [GitHub](https://github.com/) account is required.
[Setup Packages Feed](setup.md){ .md-button .md-button--primary }
!!! info
The packages feed includes all dependencies that are not available on [nuget.org](https://nuget.org/).
This includes some third-party libraries that have been patched for extended maintenance.
## Data and Recorder APIs
[_Read and Write McLaren Telemetry data_](../sql-race/index.md)
**MESL.SQLRace.API**
: Data API, for reading and writing telemetry with McLaren SSN2 files and SQL Server databases;
Supports .NET Framework 4.8
**MESL.SQLRace.RTA**
: Adds [RTA](#rta) support for SQL Race (above);
Supports .NET Framework 4.8
**MAT.ATLAS.SupportFiles**
: Adds SSN (read-only) support to SQL Race (above), and provides headless Recorder APIs;
Supports .NET Framework 4.8;
Requires [Microsoft Visual C++ 2015-19 Redistributable (x64)](https://aka.ms/vs/16/release/vc_redist.x64.exe)
## ATLAS Display API
[_Create custom display plugins for ATLAS_](../display-api/index.md)
**Atlas.DisplayAPI**
: ATLAS plugin API for creating custom displays;
Supports .NET Framework 4.8
## RTA
[_Integrate ATLAS with existing environments using Web Services_](../../rta/downloads.md)
**MAT.OCS.RTA.API**
: Client API for testing and integration;
Supports .NET Standard 2.0 and 2.1
**MAT.OCS.RTA.Services.AspNetCore**
: By far the quickest way to get a new RTA service off the ground;
Supports ASP.NET Core 2.1, 3.1 and 5.0
**MAT.OCS.RTA.Toolkit.API.GrpcClients**
: Pre-compiled gRPC clients for the RTA Toolkit Services;
Supports .NET Standard 2.1 and .NET 5.0
## ATLAS Streaming
**MAT.OCS.Streaming**
: Streaming telemetry client compatible with the ATLAS technology platform
**MAT.OCS.Streaming.Kafka**
: Provides an Apache Kafka client for MAT.OCS.Streaming
**MAT.OCS.Streaming.Codecs.Protobuf**
: Provides a faster, more compact serialization for telemetry data and samples;
Prefer this codec when working with large topics
---
# Setup Guide
First, [Create a Personal Access Token (PAT)](https://github.com/settings/tokens/new) including the _read:packages_ scope.
You'll need a free [GitHub account](https://github.com/signup).
Copy the token for reference. It will look something like:
ghp_yLKCoOLozKbaErgl4mCLDtkEKFw6Uq4D3Yyx
=== "Visual Studio"
Select _Tools > NuGet Package Manager > Package Manager Settings > Package Sources_
Click the ➕ icon, and fill in:
_Name:_ McLaren Applied GitHub Packages
_Source:_ https://nuget.pkg.github.com/mat-docs/index.json

Click _Update_ to save the changes.
When prompted for credentials, enter your GitHub username and PAT:
{ style="background-color: white; border: 1px solid #282829; padding-top: 4px" }
=== "Command Line"
From the terminal, replacing `"your_username"` and `"your_pat"`:
nuget sources Add -Name "McLaren Applied GitHub Packages" -Username "your_username" -Password "your_pat" -Source "https://nuget.pkg.github.com/mat-docs/index.json"
or:
dotnet nuget add source --name "McLaren Applied GitHub Packages" --username "your_username" --password "your_pat" "https://nuget.pkg.github.com/mat-docs/index.json"
=== "Adding to NuGet.Config"
In scripted environments, it can be convenient to add the PAT to a _NuGet.Config_ file.
!!! caution
Do not commit credentials into source control.
```xml
```
To add this `#!xml ` section from an _Azure DevOps_ YAML build:
```yaml
steps:
- task: NuGetToolInstaller@1
inputs:
versionSpec: "5.8.0"
- task: DotNetCoreCLI@2
displayName: "dotnet nuget update source (authenticate)"
inputs:
command: custom
custom: nuget
arguments: update source McLarenApplied --username "your_username" --password "your_pat" --store-password-in-clear-text --configfile NuGet.Config
verbosity: "Normal"
```
---
# Overview
The configuration API is a new multi-platform API for ECU programming and monitoring,
which makes it easier to handle multiple units, and to integrate across the network
with clients written in languages including C#, C++, Python, Java or Go. The
Configuration Service provides a modern, cross-platform [gRPC](https://grpc.io/)
interface, and mediates access to the units – via System Monitor – across the network
from multiple clients.


All information available via the COM API will be available via the Configuration
Service.
All calls to the API are managed on a single threaded basis and any subsequent calls are
blocked until previous requests are completed.
Measurement values are cached within the API server to provide the fastest possible
response time to requests, these calls are not blocked due to other actions. The rate of
cache update is configurable.
A .NET Standard [client NuGet package](https://github.com/mat-docs/packages/pkgs/nuget/SystemMonitorConfigurationAPI)
and [interface definitions](https://github.com/mat-docs/System.Monitor.Configuration.API.Client.Sample/tree/cf34ad478c086dc43d2863b74f5516946049eaca/Protos)
are provided to make it easy to create interoperable tools using any mainstream language or platform.
This feature is available from System Monitor version 8.85 onwards.
## Migrated Methods Tracker
---
# Protocol Documentation
## Table of Contents
- [Protos/system_monitor_common.proto](#Protos_system_monitor_common-proto)
- [AppParametersFileRequest](#system_monitor_common-AppParametersFileRequest)
- [AppParametersRequest](#system_monitor_common-AppParametersRequest)
- [AppRequest](#system_monitor_common-AppRequest)
- [ConversionRequest](#system_monitor_common-ConversionRequest)
- [FileRequest](#system_monitor_common-FileRequest)
- [ParameterRequest](#system_monitor_common-ParameterRequest)
- [ParametersFileRequest](#system_monitor_common-ParametersFileRequest)
- [ParametersRequest](#system_monitor_common-ParametersRequest)
- [Return](#system_monitor_common-Return)
- [BufferType](#system_monitor_common-BufferType)
- [ByteOrder](#system_monitor_common-ByteOrder)
- [ConversionType](#system_monitor_common-ConversionType)
- [DataType](#system_monitor_common-DataType)
- [ErrorCode](#system_monitor_common-ErrorCode)
- [ErrorStatus](#system_monitor_common-ErrorStatus)
- [EventPriority](#system_monitor_common-EventPriority)
- [FileType](#system_monitor_common-FileType)
- [LoggingType](#system_monitor_common-LoggingType)
- [ParameterType](#system_monitor_common-ParameterType)
- [Reason](#system_monitor_common-Reason)
- [TriggerOperator](#system_monitor_common-TriggerOperator)
- [TriggerType](#system_monitor_common-TriggerType)
- [Protos/system_monitor_logging.proto](#Protos_system_monitor_logging-proto)
- [AddParameterRequest](#system_monitor_logging-AddParameterRequest)
- [AddVirtualParameterRequest](#system_monitor_logging-AddVirtualParameterRequest)
- [ChannelProperties](#system_monitor_logging-ChannelProperties)
- [ChannelPropertiesReply](#system_monitor_logging-ChannelPropertiesReply)
- [ChannelRequest](#system_monitor_logging-ChannelRequest)
- [ClearRequest](#system_monitor_logging-ClearRequest)
- [ConfigReply](#system_monitor_logging-ConfigReply)
- [DownloadProgressReply](#system_monitor_logging-DownloadProgressReply)
- [DownloadReply](#system_monitor_logging-DownloadReply)
- [DownloadRequest](#system_monitor_logging-DownloadRequest)
- [GetSessionDetailReply](#system_monitor_logging-GetSessionDetailReply)
- [GetSessionDetailRequest](#system_monitor_logging-GetSessionDetailRequest)
- [LoggingChannelValue](#system_monitor_logging-LoggingChannelValue)
- [LoggingDurationReply](#system_monitor_logging-LoggingDurationReply)
- [LoggingOffsetReply](#system_monitor_logging-LoggingOffsetReply)
- [LoggingOffsetRequest](#system_monitor_logging-LoggingOffsetRequest)
- [LoggingParameter](#system_monitor_logging-LoggingParameter)
- [LoggingParametersReply](#system_monitor_logging-LoggingParametersReply)
- [SetSessionDetailRequest](#system_monitor_logging-SetSessionDetailRequest)
- [SlotCountReply](#system_monitor_logging-SlotCountReply)
- [SlotPercentageReply](#system_monitor_logging-SlotPercentageReply)
- [Trigger](#system_monitor_logging-Trigger)
- [TriggerCondition](#system_monitor_logging-TriggerCondition)
- [TriggerRequest](#system_monitor_logging-TriggerRequest)
- [TriggersReply](#system_monitor_logging-TriggersReply)
- [WrapReply](#system_monitor_logging-WrapReply)
- [WrapRequest](#system_monitor_logging-WrapRequest)
- [SystemMonitorLogging](#system_monitor_logging-SystemMonitorLogging)
- [Protos/system_monitor_parameter.proto](#Protos_system_monitor_parameter-proto)
- [AddressReply](#system_monitor_parameter-AddressReply)
- [AppArray1dParameterValuesRequest](#system_monitor_parameter-AppArray1dParameterValuesRequest)
- [AppArray2dParameterValuesRequest](#system_monitor_parameter-AppArray2dParameterValuesRequest)
- [AppParameterValuesRequest](#system_monitor_parameter-AppParameterValuesRequest)
- [AppStringParameterValuesRequest](#system_monitor_parameter-AppStringParameterValuesRequest)
- [AppTypeRequest](#system_monitor_parameter-AppTypeRequest)
- [Array1dParameterErrorsReply](#system_monitor_parameter-Array1dParameterErrorsReply)
- [Array1dParameterSetValue](#system_monitor_parameter-Array1dParameterSetValue)
- [Array1dParameterValue](#system_monitor_parameter-Array1dParameterValue)
- [Array1dValueReply](#system_monitor_parameter-Array1dValueReply)
- [Array1dValues](#system_monitor_parameter-Array1dValues)
- [Array2dParameterErrorsReply](#system_monitor_parameter-Array2dParameterErrorsReply)
- [Array2dParameterSetValue](#system_monitor_parameter-Array2dParameterSetValue)
- [Array2dParameterValue](#system_monitor_parameter-Array2dParameterValue)
- [Array2dValueReply](#system_monitor_parameter-Array2dValueReply)
- [Array2dValues](#system_monitor_parameter-Array2dValues)
- [AxisParametersReply](#system_monitor_parameter-AxisParametersReply)
- [BitMaskReply](#system_monitor_parameter-BitMaskReply)
- [BitShiftReply](#system_monitor_parameter-BitShiftReply)
- [ByteOrderReply](#system_monitor_parameter-ByteOrderReply)
- [CANParameterProperties](#system_monitor_parameter-CANParameterProperties)
- [CANParameterPropertiesReply](#system_monitor_parameter-CANParameterPropertiesReply)
- [Conversion](#system_monitor_parameter-Conversion)
- [ConversionListReply](#system_monitor_parameter-ConversionListReply)
- [ConversionNoAppRequest](#system_monitor_parameter-ConversionNoAppRequest)
- [ConversionTypeReply](#system_monitor_parameter-ConversionTypeReply)
- [ExternalParameterRequest](#system_monitor_parameter-ExternalParameterRequest)
- [ExternalReply](#system_monitor_parameter-ExternalReply)
- [ExternalRequest](#system_monitor_parameter-ExternalRequest)
- [FormulaConversionReply](#system_monitor_parameter-FormulaConversionReply)
- [FormulaConversionRequest](#system_monitor_parameter-FormulaConversionRequest)
- [LoggableReply](#system_monitor_parameter-LoggableReply)
- [MapPropertiesReply](#system_monitor_parameter-MapPropertiesReply)
- [OffsetReply](#system_monitor_parameter-OffsetReply)
- [OffsetRequest](#system_monitor_parameter-OffsetRequest)
- [Parameter](#system_monitor_parameter-Parameter)
- [ParameterErrorsReply](#system_monitor_parameter-ParameterErrorsReply)
- [ParameterGroup](#system_monitor_parameter-ParameterGroup)
- [ParameterGroupsReply](#system_monitor_parameter-ParameterGroupsReply)
- [ParameterListReply](#system_monitor_parameter-ParameterListReply)
- [ParameterProperties](#system_monitor_parameter-ParameterProperties)
- [ParameterPropertiesReply](#system_monitor_parameter-ParameterPropertiesReply)
- [ParameterSetValue](#system_monitor_parameter-ParameterSetValue)
- [ParameterTypeRequest](#system_monitor_parameter-ParameterTypeRequest)
- [ParameterValue](#system_monitor_parameter-ParameterValue)
- [ParametersReply](#system_monitor_parameter-ParametersReply)
- [RationalConversionReply](#system_monitor_parameter-RationalConversionReply)
- [RationalConversionRequest](#system_monitor_parameter-RationalConversionRequest)
- [RowDetailsReply](#system_monitor_parameter-RowDetailsReply)
- [RowValues](#system_monitor_parameter-RowValues)
- [StringParameterErrorsReply](#system_monitor_parameter-StringParameterErrorsReply)
- [StringParameterSetValue](#system_monitor_parameter-StringParameterSetValue)
- [StringParameterValue](#system_monitor_parameter-StringParameterValue)
- [StringValueReply](#system_monitor_parameter-StringValueReply)
- [TableConversion](#system_monitor_parameter-TableConversion)
- [TableConversionReply](#system_monitor_parameter-TableConversionReply)
- [TableConversionRequest](#system_monitor_parameter-TableConversionRequest)
- [TextConversion](#system_monitor_parameter-TextConversion)
- [TextConversionReply](#system_monitor_parameter-TextConversionReply)
- [TextConversionRequest](#system_monitor_parameter-TextConversionRequest)
- [UndoRequest](#system_monitor_parameter-UndoRequest)
- [ValueReply](#system_monitor_parameter-ValueReply)
- [WarningLimitsReply](#system_monitor_parameter-WarningLimitsReply)
- [WarningLimitsRequest](#system_monitor_parameter-WarningLimitsRequest)
- [SystemMonitorParameter](#system_monitor_parameter-SystemMonitorParameter)
- [Protos/system_monitor_project.proto](#Protos_system_monitor_project-proto)
- [ActiveAppReply](#system_monitor_project-ActiveAppReply)
- [AppFileRequest](#system_monitor_project-AppFileRequest)
- [AppReply](#system_monitor_project-AppReply)
- [Application](#system_monitor_project-Application)
- [CANMergeRequest](#system_monitor_project-CANMergeRequest)
- [CANRequest](#system_monitor_project-CANRequest)
- [CompareAppReply](#system_monitor_project-CompareAppReply)
- [CompareAppRequest](#system_monitor_project-CompareAppRequest)
- [CompareParameter](#system_monitor_project-CompareParameter)
- [DTVModifiedReply](#system_monitor_project-DTVModifiedReply)
- [DTVSaveCopyRequest](#system_monitor_project-DTVSaveCopyRequest)
- [DTVSaveIncrementRequest](#system_monitor_project-DTVSaveIncrementRequest)
- [DTVSaveRequest](#system_monitor_project-DTVSaveRequest)
- [DTVSavedOnReply](#system_monitor_project-DTVSavedOnReply)
- [DetailsRequest](#system_monitor_project-DetailsRequest)
- [EnableRequest](#system_monitor_project-EnableRequest)
- [ErrorDefinition](#system_monitor_project-ErrorDefinition)
- [ErrorDefinitionsReply](#system_monitor_project-ErrorDefinitionsReply)
- [ErrorInstance](#system_monitor_project-ErrorInstance)
- [ErrorReply](#system_monitor_project-ErrorReply)
- [Event](#system_monitor_project-Event)
- [EventReply](#system_monitor_project-EventReply)
- [EventRequest](#system_monitor_project-EventRequest)
- [EventsReply](#system_monitor_project-EventsReply)
- [ExistsReply](#system_monitor_project-ExistsReply)
- [ExistsRequest](#system_monitor_project-ExistsRequest)
- [FileDetailsReply](#system_monitor_project-FileDetailsReply)
- [FileNameRequest](#system_monitor_project-FileNameRequest)
- [FileNewRequest](#system_monitor_project-FileNewRequest)
- [FileOpenRequest](#system_monitor_project-FileOpenRequest)
- [FileReply](#system_monitor_project-FileReply)
- [FileSaveRequest](#system_monitor_project-FileSaveRequest)
- [GetAppDetailsReply](#system_monitor_project-GetAppDetailsReply)
- [GetBuildNumberReply](#system_monitor_project-GetBuildNumberReply)
- [GetVersionNumberReply](#system_monitor_project-GetVersionNumberReply)
- [MatlabDTVRequest](#system_monitor_project-MatlabDTVRequest)
- [MatlabRequest](#system_monitor_project-MatlabRequest)
- [MatlabSelectedRequest](#system_monitor_project-MatlabSelectedRequest)
- [MultiAppReply](#system_monitor_project-MultiAppReply)
- [MultiAppRequest](#system_monitor_project-MultiAppRequest)
- [PGVIDReply](#system_monitor_project-PGVIDReply)
- [ParameterIdRequest](#system_monitor_project-ParameterIdRequest)
- [ProjectCloseRequest](#system_monitor_project-ProjectCloseRequest)
- [ProjectCreateRequest](#system_monitor_project-ProjectCreateRequest)
- [ProjectExportRequest](#system_monitor_project-ProjectExportRequest)
- [ProjectImportRequest](#system_monitor_project-ProjectImportRequest)
- [ProjectSaveAsRequest](#system_monitor_project-ProjectSaveAsRequest)
- [ProjectSaveRequest](#system_monitor_project-ProjectSaveRequest)
- [ReasonCode](#system_monitor_project-ReasonCode)
- [ReprogramRequest](#system_monitor_project-ReprogramRequest)
- [SensorRequest](#system_monitor_project-SensorRequest)
- [SlotActiveRequest](#system_monitor_project-SlotActiveRequest)
- [SlotReply](#system_monitor_project-SlotReply)
- [SlotRequest](#system_monitor_project-SlotRequest)
- [SyncedReply](#system_monitor_project-SyncedReply)
- [SystemMonitorProject](#system_monitor_project-SystemMonitorProject)
- [Protos/system_monitor_system.proto](#Protos_system_monitor_system-proto)
- [BatchModeRequest](#system_monitor_system-BatchModeRequest)
- [CreatePGVReply](#system_monitor_system-CreatePGVReply)
- [CreatePGVRequest](#system_monitor_system-CreatePGVRequest)
- [DeviceProperties](#system_monitor_system-DeviceProperties)
- [DevicePropertiesReply](#system_monitor_system-DevicePropertiesReply)
- [FolderReply](#system_monitor_system-FolderReply)
- [LicenceDetailsReply](#system_monitor_system-LicenceDetailsReply)
- [LiveLoggingReply](#system_monitor_system-LiveLoggingReply)
- [LiveLoggingRequest](#system_monitor_system-LiveLoggingRequest)
- [LiveUpdateRequest](#system_monitor_system-LiveUpdateRequest)
- [MultiApplicationBaseInfo](#system_monitor_system-MultiApplicationBaseInfo)
- [MultiApplicationBasesReply](#system_monitor_system-MultiApplicationBasesReply)
- [MultiApplicationBasesRequest](#system_monitor_system-MultiApplicationBasesRequest)
- [OnlineRequest](#system_monitor_system-OnlineRequest)
- [SendMessageReply](#system_monitor_system-SendMessageReply)
- [SendMessageRequest](#system_monitor_system-SendMessageRequest)
- [StatusReply](#system_monitor_system-StatusReply)
- [UnitByIndexRequest](#system_monitor_system-UnitByIndexRequest)
- [UnitByIndexTypeRequest](#system_monitor_system-UnitByIndexTypeRequest)
- [UnitInfo](#system_monitor_system-UnitInfo)
- [UnitListReply](#system_monitor_system-UnitListReply)
- [UnitNameReply](#system_monitor_system-UnitNameReply)
- [LinkStatus](#system_monitor_system-LinkStatus)
- [SystemMonitorSystem](#system_monitor_system-SystemMonitorSystem)
- [Protos/system_monitor_virtual.proto](#Protos_system_monitor_virtual-proto)
- [AddGroupRequest](#system_monitor_virtual-AddGroupRequest)
- [VirtualExportRequest](#system_monitor_virtual-VirtualExportRequest)
- [VirtualGroupReply](#system_monitor_virtual-VirtualGroupReply)
- [VirtualGroupRequest](#system_monitor_virtual-VirtualGroupRequest)
- [VirtualGroupsReply](#system_monitor_virtual-VirtualGroupsReply)
- [VirtualParameter](#system_monitor_virtual-VirtualParameter)
- [VirtualParameterDataTypeRequest](#system_monitor_virtual-VirtualParameterDataTypeRequest)
- [VirtualParameterProperties](#system_monitor_virtual-VirtualParameterProperties)
- [VirtualParameterPropertiesReply](#system_monitor_virtual-VirtualParameterPropertiesReply)
- [VirtualParameterRequest](#system_monitor_virtual-VirtualParameterRequest)
- [VirtualReply](#system_monitor_virtual-VirtualReply)
- [VirtualsRequest](#system_monitor_virtual-VirtualsRequest)
- [SystemMonitorVirtual](#system_monitor_virtual-SystemMonitorVirtual)
- [Scalar Value Types](#scalar-value-types)
## Protos/system_monitor_project.proto
### ActiveAppReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_ids | [uint32](#uint32) | repeated | Application ids |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### AppFileRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application id. |
| file_path | [string](#string) | | File path. |
### AppReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| text | [string](#string) | | Return text value. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### Application
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| app_name | [string](#string) | | Application name. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### CANMergeRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| index | [uint32](#uint32) | | Bus Index. |
| file_path | [string](#string) | | Name and path of .csv. |
| merge | [bool](#bool) | | Merge with existing messages. |
### CANRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| index | [uint32](#uint32) | | Bus Index |
| file_path | [string](#string) | | Name and path of CAN .csv file. |
### CompareAppReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| parameters | [CompareParameter](#system_monitor_project-CompareParameter) | repeated | The compared parameter information. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### CompareAppRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application id. |
| dtv1_path | [string](#string) | | Filename and full path of the first DTV to compare against (.dtv). |
| dtv2_path | [string](#string) | | Filename and full path of the second DTV to compare against (.dtv). |
### CompareParameter
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| parameter_id | [string](#string) | | Parameter id. |
| type | [system_monitor_common.ParameterType](#system_monitor_common-ParameterType) | | Parameter data type. - One of ParameterType.scalar, ParameterType.axis_1, ParameterType.axis_2, ParameterType.array, ParameterType.string, ParameterType.Can, ParameterType.Virtual, ParameterType.Axis, ParameterType.Input or ParameterType.Measurement. |
| reason1 | [ReasonCode](#system_monitor_project-ReasonCode) | | Reason codes for difference between the parameter in the application in memory and the first DTV supplied. |
| reason2 | [ReasonCode](#system_monitor_project-ReasonCode) | | Reason codes for difference between the parameter in the application in memory and the second DTV supplied. |
### DTVModifiedReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| modified | [bool](#bool) | | Whether the DTV is modified. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### DTVSaveCopyRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| save_path | [string](#string) | | Filename and full path. |
| comment | [string](#string) | | Prefix to existing comment. |
| notes | [string](#string) | | Prefix to existing notes. |
| consortium | [string](#string) | | Consortium name to save data version to. Consortium Id in the DTV will be saved with the supplied value if licence permissions allow, otherwise error code -2 is returned. Set to "Disabled" to remove team security and unlock file. |
### DTVSaveIncrementRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| comment | [string](#string) | | Prefix to existing comment. |
| notes | [string](#string) | | Prefix to existing notes. |
### DTVSaveRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| save_path | [string](#string) | | Filename and full path. |
| comment | [string](#string) | | Prefix to existing comment. |
| notes | [string](#string) | | Prefix to existing notes. |
### DTVSavedOnReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| saved_on | [string](#string) | | Timestamp the DTV was saved at. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### DetailsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| text | [string](#string) | | Data Version Notes or Comments |
### EnableRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| enable | [bool](#bool) | | True to enable, false to disable. |
### ErrorDefinition
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [string](#string) | | Error definition id. |
| name | [string](#string) | | Error definition name. |
| description | [string](#string) | | Error definition description. |
| group | [string](#string) | | Error definition group. |
| bit_number | [uint32](#uint32) | | Error definition bit number. |
| current | [string](#string) | | Error definition current parameter identifier. |
| logged | [string](#string) | | Error definition logged parameter identifier. |
### ErrorDefinitionsReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error_definitions | [ErrorDefinition](#system_monitor_project-ErrorDefinition) | repeated | The error definitions. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### ErrorInstance
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| name | [string](#string) | | Error identifier. |
| description | [string](#string) | | Error description. |
| status | [system_monitor_common.ErrorStatus](#system_monitor_common-ErrorStatus) | | Error status level. |
### ErrorReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error_instances | [ErrorInstance](#system_monitor_project-ErrorInstance) | repeated | The active errors |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### Event
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [uint32](#uint32) | | Event id. |
| name | [string](#string) | | Event name. |
| priority | [system_monitor_common.EventPriority](#system_monitor_common-EventPriority) | | Event priority. |
### EventReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| event_id | [uint32](#uint32) | | Event Id. |
| description | [string](#string) | | Event description. |
| conversion_id1 | [string](#string) | | Id of first event conversion. |
| conversion_id2 | [string](#string) | | Id of second event conversion. |
| conversion_id3 | [string](#string) | | Id of third event conversion. |
| priority | [system_monitor_common.EventPriority](#system_monitor_common-EventPriority) | | Event level. ( 0 - High, 1 - Medium, 2 - Low, 3 - Debug ) |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### EventRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application id. |
| event_id | [uint32](#uint32) | | Event id. |
### EventsReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| events | [Event](#system_monitor_project-Event) | repeated | The events. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### ExistsReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| exists | [bool](#bool) | | True if exists, False if not |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### ExistsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| parameter_id | [string](#string) | | Parameter Id. |
| data_type | [system_monitor_common.ParameterType](#system_monitor_common-ParameterType) | | Parameter data type. - One of ParameterType.scalar, ParameterType.axis_1, ParameterType.axis_2, ParameterType.array, ParameterType.string, ParameterType.Can, ParameterType.Virtual, ParameterType.Axis, ParameterType.Input or ParameterType.Measurement. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### FileDetailsReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| saved_by | [string](#string) | | Name of the last user to save the file. |
| saved_on | [google.protobuf.Timestamp](https://protobuf.dev/reference/php/api-docs/Google/Protobuf/Timestamp.html) | | Date time of last file save. |
| comment | [string](#string) | | File comments. |
| notes | [string](#string) | | File notes. |
| build | [uint32](#uint32) | | Build number of System Monitor used when saving file. |
| consortium | [string](#string) | | Name of the licence consortium used to save the file. Set for supported file types only ( .dtv, .rlc & .dtp ). |
| owner | [string](#string) | | Name of the licence owner used to create the file. Set for supported file types only ( .dtv, .rlc & .dtp ). |
| rda | [string](#string) | | RDA unlock list checksum for locked DTV's.Set for supported file types only ( .dtv ). |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### FileNameRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| file_type | [system_monitor_common.FileType](#system_monitor_common-FileType) | | File name of requested type. - One of FileType.Project, FileType.Desktop, FileType.Virtuals, FileType.LoggingConfig or FileType.Can. |
| slot | [uint32](#uint32) | | Slot index (1-8). Only required for FileType.LoggingConfig and FileType.Can |
### FileNewRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| file_type | [system_monitor_common.FileType](#system_monitor_common-FileType) | | Type of file to create. - One of FileType.Virtuals, FileType.LoggingConfig or FileType.Can. |
| file_path | [string](#string) | | The path of the file to create. |
| save_existing | [bool](#bool) | | Whether to save the existing file. |
| overwrite | [bool](#bool) | | Whether to overwrite an existing file with the same path. |
### FileOpenRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| file_type | [system_monitor_common.FileType](#system_monitor_common-FileType) | | The type of file to open. - One of FileType.Desktop, FileType.Virtuals, FileType.LoggingConfig or FileType.Can. |
| file_path | [string](#string) | | The path of the file to open. |
| slot | [uint32](#uint32) | | Slot index. Only required when loading Logging and CAN configuration (1-8). |
| activate | [bool](#bool) | | True to set active. Only required when loading Logging and CAN configuration (1-8). |
### FileReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| file_path | [string](#string) | | File path including folder. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### FileSaveRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| file_type | [system_monitor_common.FileType](#system_monitor_common-FileType) | | Type of file to save. - One of FileType.Desktop, FileType.Virtuals, FileType.LoggingConfig or FileType.Can. |
| file_path | [string](#string) | | The path of the file to save. |
| comment | [string](#string) | | File comments. |
| notes | [string](#string) | | File notes. |
| consortium | [string](#string) | | Name of the licence consortium used to save the file. Set for supported file types only ( .dtv, .rlc & .dtp ). |
| save_copy_as | [bool](#bool) | | Whether to save a copy without affecting SM modified status. |
### GetAppDetailsReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| apps | [Application](#system_monitor_project-Application) | repeated | Application details. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### GetBuildNumberReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| build_number | [uint32](#uint32) | | System Monitor build number. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### GetVersionNumberReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| major_version | [uint32](#uint32) | | Major revision. |
| minor_version | [uint32](#uint32) | | Minor revision. |
| build_version | [uint32](#uint32) | | Build number. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### MatlabDTVRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| dtv_path | [string](#string) | | Filename and full path of DTV file. |
| export_path | [string](#string) | | Filename and full path of exported file. |
| data_only | [bool](#bool) | | True if only data is to be exported, false to export data and definitions. |
| data_types | [system_monitor_common.ParameterType](#system_monitor_common-ParameterType) | repeated | Parameter data types included in export. - One or more of ParameterType.scalar, ParameterType.axis_1, ParameterType.axis_2, ParameterType.array, ParameterType.string, ParameterType.Can, ParameterType.Virtual, ParameterType.Axis, ParameterType.Input or ParameterType.Measurement. |
### MatlabRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| export_path | [string](#string) | | Filename and full path. |
| data_only | [bool](#bool) | | True if only data is to be exported, false to export data and definitions. |
| data_types | [system_monitor_common.ParameterType](#system_monitor_common-ParameterType) | repeated | Parameter data types included in export. - One or more of ParameterType.scalar, ParameterType.axis_1, ParameterType.axis_2, ParameterType.array, ParameterType.string, ParameterType.Can, ParameterType.Virtual, ParameterType.Axis, ParameterType.Input or ParameterType.Measurement. |
### MatlabSelectedRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| export_path | [string](#string) | | Filename and full path. |
| data_only | [bool](#bool) | | True if only data is to be exported, false to export data and definitions. |
| parameter_ids | [string](#string) | repeated | Identifiers of the parameters to be exported |
### MultiAppReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_ids | [uint32](#uint32) | repeated | Applications containing the specified parameter. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | |
### MultiAppRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_ids | [uint32](#uint32) | repeated | Application identifiers. |
### PGVIDReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| pgv_id | [uint32](#uint32) | | Result program version ID. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### ParameterIdRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| parameter_id | [string](#string) | | Parameter identifier. |
### ProjectCloseRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| action | [int32](#int32) | | Action to perform when unsaved documents encountered on closing project. 0 - Cancel Save. 1 - Save All. 2 - Save None. |
### ProjectCreateRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| project_path | [string](#string) | | Project name to be created within the current multi-application base. |
| app_paths | [string](#string) | repeated | Array of PGV files to be included. |
| desktop_path | [string](#string) | | Name of desktop document to be created or included if file already exists. |
| virtuals_path | [string](#string) | | Optional name of virtual parameters document to be created or included if file already exists. |
| can_path | [string](#string) | | Optional name of CAN configuration document to be created or included if file already exists. |
| logging_config_path | [string](#string) | | Optional name of remote logging configuration document to be created or included if file already exists. |
### ProjectExportRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| save_modified | [bool](#bool) | | Flag to indicate if any unsaved files in the project should be saved before exporting. |
### ProjectImportRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| project_path | [string](#string) | | SMX file containing project to be imported. |
| base | [string](#string) | | Optional Multi-Application base name for import. If blank, the current default base is used. |
### ProjectSaveAsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| project_name | [string](#string) | | Name of renamed project file. |
| save_all | [bool](#bool) | | If TRUE then all modified files are saved. If FALSE then only the project file is saved. |
| comments | [string](#string) | | New project comments. |
| notes | [string](#string) | | New project notes. |
### ProjectSaveRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| save_all | [bool](#bool) | | If TRUE then all modified files are saved. If FALSE then only the project file is saved. |
### ReasonCode
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| reasons | [system_monitor_common.Reason](#system_monitor_common-Reason) | repeated | Reason codes. |
### ReprogramRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_ids | [uint32](#uint32) | repeated | An array of all app ids to reprogram. |
| force | [bool](#bool) | | Whether to force a reprogram. |
### SensorRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| app_id | [uint32](#uint32) | | Application Id. |
| sensor | [string](#string) | | Sensor identifier. |
| serial_number | [int32](#int32) | | Serial number. |
### SlotActiveRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| slot | [uint32](#uint32) | | Slot index (1-8). |
| active | [bool](#bool) | | TRUE to activate the slot. |
### SlotReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| active | [bool](#bool) | | Slot is active. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | return code. |
### SlotRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| slot | [uint32](#uint32) | | Slot index (1-8). |
### SyncedReply
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| synced | [bool](#bool) | | TRUE if the edit buffer is in sync with the ECU. |
| return_code | [system_monitor_common.ErrorCode](#system_monitor_common-ErrorCode) | | Return code. |
### SystemMonitorProject
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| ProjectOpen | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Opens a Project. |
| ProjectClose | [ProjectCloseRequest](#system_monitor_project-ProjectCloseRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Closes a Project. |
| ProjectCreate | [ProjectCreateRequest](#system_monitor_project-ProjectCreateRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Create a new project. If full path names are used, the path must lie within the current multi-application base. |
| ProjectSave | [ProjectSaveRequest](#system_monitor_project-ProjectSaveRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Saves the current project. |
| ProjectSaveAs | [ProjectSaveAsRequest](#system_monitor_project-ProjectSaveAsRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Saves the current project as a new project. |
| ProjectImport | [ProjectImportRequest](#system_monitor_project-ProjectImportRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Imports the project from a .smx file. |
| ProjectExport | [ProjectExportRequest](#system_monitor_project-ProjectExportRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the project to a .smx file. |
| Reprogram | [ReprogramRequest](#system_monitor_project-ReprogramRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Reprograms the ECU. |
| DownloadDataChanges | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Causes any modifications made to the System Monitor edit buffer to be downloaded to the ECU. |
| EditBufferSynced | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [SyncedReply](#system_monitor_project-SyncedReply) | Identifies whether the edit buffer is in sync with the ECU. |
| UploadDataVersion | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Uploads specified data version to the edit buffer. |
| GetVersionNumber | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [GetVersionNumberReply](#system_monitor_project-GetVersionNumberReply) | Gets the version information contained within the System Monitor executable. |
| GetPGVVersion | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [AppReply](#system_monitor_project-AppReply) | Gets the filepath for the .pgv of an application by Application Id. |
| GetPGVID | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [PGVIDReply](#system_monitor_project-PGVIDReply) | Gets the program version ID of the currently loaded program version. |
| GetDTVVersion | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [AppReply](#system_monitor_project-AppReply) | Returns the filename of the data version in the edit buffer. |
| GetEcuDTVVersion | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [AppReply](#system_monitor_project-AppReply) | Returns the filename of the data version on the ECU. |
| GetNextDTVVersion | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [AppReply](#system_monitor_project-AppReply) | Returns the filename of the next data version that will be saved if the user selects, File, Save. If the edit buffer is unmodified, this will be the name of the current data version in the edit buffer. |
| GetDTVModified | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [DTVModifiedReply](#system_monitor_project-DTVModifiedReply) | Gets the modified state associated with the DTV. |
| GetDTVSavedOn | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [DTVSavedOnReply](#system_monitor_project-DTVSavedOnReply) | Gets the contents of the saved on attribute associated with the DTV. |
| GetDTVNotes | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [AppReply](#system_monitor_project-AppReply) | Returns the contents of the notes attribute associated with the DTV. |
| SetDTVNotes | [DetailsRequest](#system_monitor_project-DetailsRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Sets the Data Version notes for the specified application. |
| ClearDTVNotes | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Clears the contents of the notes attribute associated with the DTV. |
| GetDTVComment | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [AppReply](#system_monitor_project-AppReply) | Gets the contents of the comments attribute associated with the DTV. |
| SetDTVComment | [DetailsRequest](#system_monitor_project-DetailsRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Sets the Data Version comment for the specified application. |
| EnableDTVBackup | [EnableRequest](#system_monitor_project-EnableRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Enables/Disables the data version backup during parameter value changes. Adds a message to the log file to indicate when changed. NOTE: Any changes to the data version whilst backups are suspended are not flushed to the backup file when the backups are re- enabled. |
| DTVOpen | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Opens the specified data version file. |
| DTVSave | [DTVSaveRequest](#system_monitor_project-DTVSaveRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Saves the current data version to the specified file. |
| DTVSaveCopy | [DTVSaveCopyRequest](#system_monitor_project-DTVSaveCopyRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Saves the current data version to the specified file, without modifying the data version in the edit buffer. |
| DTVSaveIncrement | [DTVSaveIncrementRequest](#system_monitor_project-DTVSaveIncrementRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Increments the version number of the data version and then performs a save. |
| GetBuildNumber | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [GetBuildNumberReply](#system_monitor_project-GetBuildNumberReply) | Gets the build number of System Monitor (SM-V7). Client code may be branched on the basis of build number, thereby providing a way by which a single client script can be written which works with releases of SM-V7 which have different ActiveX interfaces. |
| GetAppDetails | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [GetAppDetailsReply](#system_monitor_project-GetAppDetailsReply) | Gets details of the applications in the current project. |
| GetActiveApps | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [ActiveAppReply](#system_monitor_project-ActiveAppReply) | Gets details of all the active applications. |
| SetActiveApps | [MultiAppRequest](#system_monitor_project-MultiAppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Sets the active application when provided with an application ID. |
| AddApp | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Adds the application defined by the given DTV and it's associated PGV into the project. If the application already exists in the project the error: SMAPI_ERR_INVALID_CMD (-31) will be returned. |
| RemoveApp | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Removes the given application from the project. The requested application cannot be the BIOS. |
| CompareApp | [CompareAppRequest](#system_monitor_project-CompareAppRequest) | [CompareAppReply](#system_monitor_project-CompareAppReply) | Perform a compare between an application loaded in memory and up to two DTV's. When two DTV's are used both must have the same PGV version. Returns a list of parameters that contain differences along with the parameter data type and a reason code identifying the difference. |
| GetAppPULFile | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [FileReply](#system_monitor_project-FileReply) | Get the name of the unlock list PUL file for the given application id. |
| SetAppPULFile | [AppFileRequest](#system_monitor_project-AppFileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Set the unlock list PUL file on the given application id. Licence ownership restrictions apply |
| GenerateParamSet | [.system_monitor_common.ParametersFileRequest](#system_monitor_common-ParametersFileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Generate a parameter set file. |
| GeneratePULFile | [.system_monitor_common.AppParametersFileRequest](#system_monitor_common-AppParametersFileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Generate a PUL file for an application for use with Reduced Data Access. NOTE: On creation of PUL file the name will be adjusted from the requested name by including the checksum. This is required to reduce file lookup times. |
| GeneratePULFileFromParamSet | [AppFileRequest](#system_monitor_project-AppFileRequest) | [FileReply](#system_monitor_project-FileReply) | Generate a PUL file for an application for use with Reduced Data Access from a saved Parameter Set file. NOTE: On creation of PUL file the name will be adjusted from the requested name by including the checksum. This is required to reduce file lookup times. The adjusted file name will be returned in pszFileName. |
| ChangeSensorSerialNumber | [SensorRequest](#system_monitor_project-SensorRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Changes the serial number of the specified sensor. |
| FileOpen | [FileOpenRequest](#system_monitor_project-FileOpenRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Opens a file within System Monitor. Supports FileType.Desktop, FileType.LoggingConfig, FileType.Virtuals, FileType.Can. |
| FileSave | [FileSaveRequest](#system_monitor_project-FileSaveRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Saves a file within System Monitor. Supports FileType.Desktop, FileType.LoggingConfig, FileType.Virtuals, FileType.Can. |
| FileNew | [FileNewRequest](#system_monitor_project-FileNewRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Creates a file within System Monitor. Supports FileType.LoggingConfig, FileType.Virtuals, FileType.Can. |
| GetFileName | [FileNameRequest](#system_monitor_project-FileNameRequest) | [FileReply](#system_monitor_project-FileReply) | Gets the name of a file from System Monitor. Supports FileType.Project, FileType.Desktop, FileType.LoggingConfig, FileType.Virtuals, FileType.Can |
| GetFileDetails | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [FileDetailsReply](#system_monitor_project-FileDetailsReply) | Gets the file details for any file type supported by System Monitor. |
| CreateFFCFromPGV | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Create an FFC File from the given PGV. Enable FFC advanced option must be set to 'Y' and full path name of PGV is required. FFC file will be created in same location as original PGV. |
| ExportToHexFile | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the selected applications PGV and DTV to a hexfile. |
| GetActiveCANConfig | [SlotRequest](#system_monitor_project-SlotRequest) | [SlotReply](#system_monitor_project-SlotReply) | Gets the active status of the CAN configuration in the given slot. |
| SetActiveCANConfig | [SlotActiveRequest](#system_monitor_project-SlotActiveRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Set the active status of the CAN configuration in the given slot. |
| GetFIACANConfig | [SlotRequest](#system_monitor_project-SlotRequest) | [SlotReply](#system_monitor_project-SlotReply) | Gets the FIA status of the CAN configuration into the given slot. |
| SetFIACANConfig | [SlotActiveRequest](#system_monitor_project-SlotActiveRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Set the FIA status of the CAN configuration into the given slot. |
| CANBuffersExport | [CANRequest](#system_monitor_project-CANRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the CAN Buffer configuration csv from the given CAN Bus index. |
| CANBuffersImport | [CANRequest](#system_monitor_project-CANRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Imports the CAN Buffer configuration csv into the given CAN Bus index. |
| CANMessagesExport | [CANRequest](#system_monitor_project-CANRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the CAN Message configuration csv from the given CAN Bus index. |
| CANMessagesImport | [CANMergeRequest](#system_monitor_project-CANMergeRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Imports the CAN Message configuration csv into the given CAN Bus index. |
| CANConfigUnload | [SlotRequest](#system_monitor_project-SlotRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Unloads the CAN configuration from the given slot. (Slot index should be 2-8). |
| GetActiveLoggingConfig | [SlotRequest](#system_monitor_project-SlotRequest) | [SlotReply](#system_monitor_project-SlotReply) | Get the active status of the remote logging configuration in the given slot. |
| SetActiveLoggingConfig | [SlotActiveRequest](#system_monitor_project-SlotActiveRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Set the active status of the remote logging configuration in the given slot. |
| LoggingConfigUnload | [SlotRequest](#system_monitor_project-SlotRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Unloads the remote logging configuration from the given slot. |
| MatlabImport | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Imports the specified MatLab-M file into System Monitor. |
| MatlabExport | [MatlabRequest](#system_monitor_project-MatlabRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the currently loaded data version to the specified file in MatLab-M format. |
| MatlabExportDTV | [MatlabDTVRequest](#system_monitor_project-MatlabDTVRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the specified data version to the specified file in MatLab-M format. |
| MatlabExportSelected | [MatlabSelectedRequest](#system_monitor_project-MatlabSelectedRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Exports the specified list of editable parameters in Matlab format. |
| AddParametersToUnlockList | [.system_monitor_common.AppParametersFileRequest](#system_monitor_common-AppParametersFileRequest) | [FileReply](#system_monitor_project-FileReply) | Update a PUL file for an application for use with Reduced Data Access by adding the requested parameter identifiers. NOTE: The PUL file name will be adjusted by including the new checksum and returned. |
| RemoveParametersFromUnlockList | [.system_monitor_common.AppParametersFileRequest](#system_monitor_common-AppParametersFileRequest) | [FileReply](#system_monitor_project-FileReply) | Update a PUL file for an application for use with Reduced Data Access by removing the requested parameter identifiers. NOTE: The PUL file the name will be adjusted by including the new checksum and returned. |
| GetAppsHoldingParam | [ParameterIdRequest](#system_monitor_project-ParameterIdRequest) | [MultiAppReply](#system_monitor_project-MultiAppReply) | Gets the applications which contain the specified parameter. |
| GetAppsHoldingMeasurementParam | [ParameterIdRequest](#system_monitor_project-ParameterIdRequest) | [MultiAppReply](#system_monitor_project-MultiAppReply) | Gets the applications which contain the specified measurement parameter. |
| GetAppsHoldingControlParam | [ParameterIdRequest](#system_monitor_project-ParameterIdRequest) | [MultiAppReply](#system_monitor_project-MultiAppReply) | Returns the applications which contain the specified non measurement parameter. |
| ParameterExists | [ExistsRequest](#system_monitor_project-ExistsRequest) | [ExistsReply](#system_monitor_project-ExistsReply) | Identifies if a parameter of the given type exists. |
| RegisterEnhancedRowParameters | [.system_monitor_common.AppParametersRequest](#system_monitor_common-AppParametersRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Add parameters from application to the enhanced speed row data list. |
| ClearEnhancedRowParameters | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Clear all parameters for given application from enhanced speed slow row data list. |
| RegisterCANEnhancedRowParameters | [.system_monitor_common.ParametersRequest](#system_monitor_common-ParametersRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Add CAN parameters to the enhanced speed row data list. |
| RegisterVirtualEnhancedRowParameters | [.system_monitor_common.ParametersRequest](#system_monitor_common-ParametersRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Add virtual parameters to the enhanced speed row data list. All parameters referenced by each virtual will be added to the list. |
| ActivateEnhancedRowParameters | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [.system_monitor_common.Return](#system_monitor_common-Return) | Activate current enhanced speed row data list. |
| DumpEvents | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Dumps the contents of the Event window to a specified file. |
| DumpErrors | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Any errors that are currently occurring are dumped to disk. |
| DumpRowData | [.system_monitor_common.FileRequest](#system_monitor_common-FileRequest) | [.system_monitor_common.Return](#system_monitor_common-Return) | Dumps the current values of all acquired measurement parameters to disk. |
| ClearEvents | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [.system_monitor_common.Return](#system_monitor_common-Return) | Clears the event window in SM-V7. |
| GetEvents | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [EventsReply](#system_monitor_project-EventsReply) | Gets the events defined for a given application. |
| GetEventDetails | [EventRequest](#system_monitor_project-EventRequest) | [EventReply](#system_monitor_project-EventReply) | Gets the details for a given event defined in an application. |
| GetErrorDefinitions | [.system_monitor_common.AppRequest](#system_monitor_common-AppRequest) | [ErrorDefinitionsReply](#system_monitor_project-ErrorDefinitionsReply) | Gets the error definitions for a given application. |
| GetErrors | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [ErrorReply](#system_monitor_project-ErrorReply) | Returns list of active errors. |
| DeleteErrors | [.google.protobuf.Empty](https://protobuf.dev/reference/protobuf/google.protobuf/#empty) | [.system_monitor_common.Return](#system_monitor_common-Return) | Clears the active errors. |
## ma/streaming/api/v1/api.proto
### AddAssociateSessionRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key of the parent session |
| associate_session_key | [string](#string) | | Unique session key of the associate session |
### AddAssociateSessionResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| success | [bool](#bool) | | Whether the add associate session request succeeded |
### CloseConnectionRequest
Request to close an existing connection
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| connection | [Connection](#ma-streaming-api-v1-Connection) | | Identifier for the connection |
### CloseConnectionResponse
Response to a close connection request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| success | [bool](#bool) | | Whether the close connection request succeeded |
### Connection
A connection identifier
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| id | [int64](#int64) | | For internal use only - do not modify this |
### ConnectionDetails
Details of a connection
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source to read from |
| session_key | [string](#string) | | Session key of the session to read (can be ommitted if sessions are not being used) |
| streams | [string](#string) | repeated | Streams to read (can be ommitted if all streams are required) |
| stream_offsets | [int64](#int64) | repeated | Offset from which to start for each stream -1 = Latest, 0 = Earliest (default) |
| main_offset | [int64](#int64) | | Offset from which to start for the main data source topic |
| essentials_offset | [int64](#int64) | | Offset from which to start for the data source essentials topic |
| exclude_main_stream | [bool](#bool) | | to specify exclusion of the main stream from reading |
### CreateSessionRequest
Request for the creation of a new session
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data Source name |
| type | [string](#string) | | Session type (defaults to "Session") |
| version | [uint32](#uint32) | | Version (defaults to 1) |
| utc_offset | [google.protobuf.Duration](https://protobuf.dev/reference/php/api-docs/Google/Protobuf/Duration.html) | | Difference between UTC time and local standard time in the timezone in which the data is recorded (negative for negative longitudes, positive for positive longitudes, defaults to 0) |
| identifier | [string](#string) | | Session identifier |
| associate_session_key | [string](#string) | repeated | List of unique session key to associate to the session |
| details | [CreateSessionRequest.DetailsEntry](#ma-streaming-api-v1-CreateSessionRequest-DetailsEntry) | repeated | Session details to update (detail name, detail value) |
### CreateSessionRequest.DetailsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [string](#string) | | |
### CreateSessionResponse
Response to a session creation request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key |
| new_session | [ma.streaming.open_data.v1.NewSessionPacket](#ma-streaming-open_data-v1-NewSessionPacket) | | New session packet |
| success | [bool](#bool) | | Whether the create session request succeeded |
### DataPacketDetails
Details for the packet being written
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| message | [ma.streaming.open_data.v1.Packet](#ma-streaming-open_data-v1-Packet) | | Packet to write |
| data_source | [string](#string) | | Data source for this packet |
| stream | [string](#string) | | Stream name to which to write |
| session_key | [string](#string) | | Unique session key of the session to which to write |
### DataPacketRequest
Request for reading parameters
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| connection | [Connection](#ma-streaming-api-v1-Connection) | | Connection to Read |
| include_parameters | [string](#string) | repeated | Parameters to include (regular expressions) |
| exclude_parameters | [string](#string) | repeated | Parameters to exclude (regular expressions) |
| include_events | [string](#string) | repeated | Events to include (regular expressions) |
| exclude_events | [string](#string) | repeated | Events to exclude (regular expressions) |
| include_markers | [bool](#bool) | | Include markers? |
### EndSessionRequest
Request to end an existing session
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source name |
| session_key | [string](#string) | | Unique session key |
### EndSessionResponse
Response to the termination of a session
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| end_session | [ma.streaming.open_data.v1.EndOfSessionPacket](#ma-streaming-open_data-v1-EndOfSessionPacket) | | End of session packet |
| success | [bool](#bool) | | Whether the end session request succeeded |
### GetConnectionRequest
Request for details of an existing connection
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| connection | [Connection](#ma-streaming-api-v1-Connection) | | Identifier for the connection |
### GetConnectionResponse
Response to a get connection request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| details | [ConnectionDetails](#ma-streaming-api-v1-ConnectionDetails) | | The connection details |
### GetCurrentSessionsRequest
Request to return all sessions present on the broker for a given data source
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source name |
### GetCurrentSessionsResponse
Response to the listing of all available sessions on the broker request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_keys | [string](#string) | repeated | List of unique session keys present on the broker for the specified data source |
| success | [bool](#bool) | | Whether the get current session request succeeded |
### GetEventDataFormatIdRequest
Request for a data format ID for a given event
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source for which this format is to be used |
| event | [string](#string) | | Event identifier |
### GetEventDataFormatIdResponse
Response for a data format request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format_identifier | [uint64](#uint64) | | Data format identifier |
### GetEventRequest
Request for an event from a data format ID
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source for which this format is used |
| data_format_identifier | [uint64](#uint64) | | Data format identifier |
### GetEventResponse
Response for an event request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| event | [string](#string) | | Event identifier |
### GetParameterDataFormatIdRequest
Request for a data format ID for a given set of parameters
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source for which this format is to be used |
| parameters | [string](#string) | repeated | Ordered of parameter identifiers (the same parameters in a different order is a different id) |
### GetParameterDataFormatIdResponse
Response for a data format request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format_identifier | [uint64](#uint64) | | Data format identifier |
### GetParametersListRequest
Request for a list of parameters from a data format ID
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source for which this format is used |
| data_format_identifier | [uint64](#uint64) | | Data format identifier |
### GetParametersListResponse
Response for a parameter list request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| parameters | [string](#string) | repeated | List of parameters |
### GetSessionInfoRequest
Request to return session info of a given session
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key |
### GetSessionInfoResponse
Response to the session info request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data Source name |
| identifier | [string](#string) | | Identifier |
| type | [string](#string) | | Type |
| version | [uint32](#uint32) | | Version |
| associate_session_keys | [string](#string) | repeated | Associate session keys |
| is_complete | [bool](#bool) | | Shows whether the session is completed or not |
| streams | [string](#string) | repeated | Available streams |
| topic_partition_offsets | [GetSessionInfoResponse.TopicPartitionOffsetsEntry](#ma-streaming-api-v1-GetSessionInfoResponse-TopicPartitionOffsetsEntry) | repeated | The offsets into each topic / partition (key is topic name, optionally appended with a ':' followed by the partition number) |
| main_offset | [int64](#int64) | | Offset of the main data source topic |
| essentials_offset | [int64](#int64) | | Offset of the data source essentials topic |
| details | [GetSessionInfoResponse.DetailsEntry](#ma-streaming-api-v1-GetSessionInfoResponse-DetailsEntry) | repeated | Session details (detail name, detail value) |
| utc_offset | [google.protobuf.Duration](https://protobuf.dev/reference/php/api-docs/Google/Protobuf/Duration.html) | | Difference between UTC time and local standard time in the timezone in which the data is recorded (negative for negative longitudes, positive for positive longitudes) |
| success | [bool](#bool) | | Whether the get session info request succeeded |
### GetSessionInfoResponse.DetailsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [string](#string) | | |
### GetSessionInfoResponse.TopicPartitionOffsetsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [int64](#int64) | | |
### GetSessionStartNotificationRequest
Request for obtaining a session start notification
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source name |
### GetSessionStartNotificationResponse
Response to a session start notification request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key of the started session |
| data_source | [string](#string) | | Data source name |
### GetSessionStopNotificationRequest
Request for obtaining a session end notification
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data source name |
### GetSessionStopNotificationResponse
Response to a session end notification request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key of the ended session |
| data_source | [string](#string) | | Data source name |
### NewConnectionRequest
Request for a new (read) connection
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| details | [ConnectionDetails](#ma-streaming-api-v1-ConnectionDetails) | | The connection details |
### NewConnectionResponse
Response to a new connection request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| connection | [Connection](#ma-streaming-api-v1-Connection) | | Identifier for the connection |
### PacketResponse
The return from a packet read
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| packet | [ma.streaming.open_data.v1.Packet](#ma-streaming-open_data-v1-Packet) | | The packet that was read |
| stream | [string](#string) | | The stream the packet was read from |
| submit_time | [google.protobuf.Timestamp](https://protobuf.dev/reference/php/api-docs/Google/Protobuf/Timestamp.html) | | the time that packet submit in the broker topic partition |
### ReadDataPacketsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| request | [DataPacketRequest](#ma-streaming-api-v1-DataPacketRequest) | | |
### ReadDataPacketsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| response | [PacketResponse](#ma-streaming-api-v1-PacketResponse) | repeated | |
### ReadEssentialsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| connection | [Connection](#ma-streaming-api-v1-Connection) | | |
### ReadEssentialsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| response | [PacketResponse](#ma-streaming-api-v1-PacketResponse) | repeated | |
### ReadPacketsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| connection | [Connection](#ma-streaming-api-v1-Connection) | | |
### ReadPacketsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| response | [PacketResponse](#ma-streaming-api-v1-PacketResponse) | repeated | |
### UpdateSessionDetailsRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key |
| details | [UpdateSessionDetailsRequest.DetailsEntry](#ma-streaming-api-v1-UpdateSessionDetailsRequest-DetailsEntry) | repeated | Session details to update (detail name, detail value) |
### UpdateSessionDetailsRequest.DetailsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [string](#string) | | |
### UpdateSessionDetailsResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| success | [bool](#bool) | | Whether the update session details request succeeded |
### UpdateSessionIdentifierRequest
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| session_key | [string](#string) | | Unique session key |
| identifier | [string](#string) | | Session identifier |
### UpdateSessionIdentifierResponse
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| success | [bool](#bool) | | Whether the update session identifier request succeeded |
### WriteDataPacketRequest
Request for writing a data packet to the stream
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| detail | [DataPacketDetails](#ma-streaming-api-v1-DataPacketDetails) | | |
### WriteDataPacketResponse
Response to a request for writing a data packet to the stream
### WriteDataPacketsRequest
Request for writing a stream of data packets
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| details | [DataPacketDetails](#ma-streaming-api-v1-DataPacketDetails) | repeated | |
### WriteDataPacketsResponse
Response to a request for writing a stream of data packets
### WriteInfoPacketRequest
Request for writing an info packet to the stream
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| message | [ma.streaming.open_data.v1.Packet](#ma-streaming-open_data-v1-Packet) | | Packet to write |
| type | [InfoType](#ma-streaming-api-v1-InfoType) | | Type for this packet |
### WriteInfoPacketResponse
Response to a request for writing an info packet to the stream
### WriteInfoPacketsRequest
Request for writing a stream of info packets
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| message | [ma.streaming.open_data.v1.Packet](#ma-streaming-open_data-v1-Packet) | | Packet to write |
| type | [InfoType](#ma-streaming-api-v1-InfoType) | | Type for this packet |
### WriteInfoPacketsResponse
Response to a request for writing a stream of info packets
### InfoType
Info type
| Name | Number | Description |
| ---- | ------ | ----------- |
| INFO_TYPE_UNSPECIFIED | 0 | Unspecified |
| INFO_TYPE_SESSION_INFO | 1 | Session info |
| INFO_TYPE_SYSTEM_STATUS | 2 | System status |
### ConnectionManagerService
Connection manager service
Open and close Connections
Connections maintain the current offset position
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| NewConnection | [NewConnectionRequest](#ma-streaming-api-v1-NewConnectionRequest) | [NewConnectionResponse](#ma-streaming-api-v1-NewConnectionResponse) | Create a new connection |
| GetConnection | [GetConnectionRequest](#ma-streaming-api-v1-GetConnectionRequest) | [GetConnectionResponse](#ma-streaming-api-v1-GetConnectionResponse) | Get an existing connection |
| CloseConnection | [CloseConnectionRequest](#ma-streaming-api-v1-CloseConnectionRequest) | [CloseConnectionResponse](#ma-streaming-api-v1-CloseConnectionResponse) | Close connection |
### DataFormatManagerService
Data format manager service
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| GetParameterDataFormatId | [GetParameterDataFormatIdRequest](#ma-streaming-api-v1-GetParameterDataFormatIdRequest) | [GetParameterDataFormatIdResponse](#ma-streaming-api-v1-GetParameterDataFormatIdResponse) | Request a data format ID for a set of parameters |
| GetEventDataFormatId | [GetEventDataFormatIdRequest](#ma-streaming-api-v1-GetEventDataFormatIdRequest) | [GetEventDataFormatIdResponse](#ma-streaming-api-v1-GetEventDataFormatIdResponse) | Request a data format ID for an event |
| GetParametersList | [GetParametersListRequest](#ma-streaming-api-v1-GetParametersListRequest) | [GetParametersListResponse](#ma-streaming-api-v1-GetParametersListResponse) | Request a list of paramters for a given data format ID |
| GetEvent | [GetEventRequest](#ma-streaming-api-v1-GetEventRequest) | [GetEventResponse](#ma-streaming-api-v1-GetEventResponse) | Request an event for a given data format ID |
### PacketReaderService
Read packets
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| ReadPackets | [ReadPacketsRequest](#ma-streaming-api-v1-ReadPacketsRequest) | [ReadPacketsResponse](#ma-streaming-api-v1-ReadPacketsResponse) stream | Continuously read all packets from the specified connection |
| ReadEssentials | [ReadEssentialsRequest](#ma-streaming-api-v1-ReadEssentialsRequest) | [ReadEssentialsResponse](#ma-streaming-api-v1-ReadEssentialsResponse) stream | Continuously read all of the essential packets from this connection |
| ReadDataPackets | [ReadDataPacketsRequest](#ma-streaming-api-v1-ReadDataPacketsRequest) | [ReadDataPacketsResponse](#ma-streaming-api-v1-ReadDataPacketsResponse) stream | Continuously read all data packets containing any of the specified parameters or events Only data packets will be returned (i.e. no config, metadata etc) |
### PacketWriterService
Packet writer service.
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| WriteDataPacket | [WriteDataPacketRequest](#ma-streaming-api-v1-WriteDataPacketRequest) | [WriteDataPacketResponse](#ma-streaming-api-v1-WriteDataPacketResponse) | Write a packet for a specified data source |
| WriteDataPackets | [WriteDataPacketsRequest](#ma-streaming-api-v1-WriteDataPacketsRequest) stream | [WriteDataPacketsResponse](#ma-streaming-api-v1-WriteDataPacketsResponse) | Continuously write a stream of data packets |
| WriteInfoPacket | [WriteInfoPacketRequest](#ma-streaming-api-v1-WriteInfoPacketRequest) | [WriteInfoPacketResponse](#ma-streaming-api-v1-WriteInfoPacketResponse) | Write an info packet of a specified type |
| WriteInfoPackets | [WriteInfoPacketsRequest](#ma-streaming-api-v1-WriteInfoPacketsRequest) stream | [WriteInfoPacketsResponse](#ma-streaming-api-v1-WriteInfoPacketsResponse) | Continuously write a stream of info packets |
### SessionManagementService
Manage sessions
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| CreateSession | [CreateSessionRequest](#ma-streaming-api-v1-CreateSessionRequest) | [CreateSessionResponse](#ma-streaming-api-v1-CreateSessionResponse) | Create a new session. Returns the unique session key |
| EndSession | [EndSessionRequest](#ma-streaming-api-v1-EndSessionRequest) | [EndSessionResponse](#ma-streaming-api-v1-EndSessionResponse) | End the session for a given unique session key |
| GetCurrentSessions | [GetCurrentSessionsRequest](#ma-streaming-api-v1-GetCurrentSessionsRequest) | [GetCurrentSessionsResponse](#ma-streaming-api-v1-GetCurrentSessionsResponse) | Get a list of the current sessions within the broker |
| GetSessionInfo | [GetSessionInfoRequest](#ma-streaming-api-v1-GetSessionInfoRequest) | [GetSessionInfoResponse](#ma-streaming-api-v1-GetSessionInfoResponse) | Get the info for a session |
| GetSessionStartNotification | [GetSessionStartNotificationRequest](#ma-streaming-api-v1-GetSessionStartNotificationRequest) | [GetSessionStartNotificationResponse](#ma-streaming-api-v1-GetSessionStartNotificationResponse) stream | Continuously notifies the client when a session starts |
| GetSessionStopNotification | [GetSessionStopNotificationRequest](#ma-streaming-api-v1-GetSessionStopNotificationRequest) | [GetSessionStopNotificationResponse](#ma-streaming-api-v1-GetSessionStopNotificationResponse) stream | Continuously notifies the client when a session ends |
| UpdateSessionIdentifier | [UpdateSessionIdentifierRequest](#ma-streaming-api-v1-UpdateSessionIdentifierRequest) | [UpdateSessionIdentifierResponse](#ma-streaming-api-v1-UpdateSessionIdentifierResponse) | Update the session identifier given its unique session key |
| AddAssociateSession | [AddAssociateSessionRequest](#ma-streaming-api-v1-AddAssociateSessionRequest) | [AddAssociateSessionResponse](#ma-streaming-api-v1-AddAssociateSessionResponse) | Add associate session to a session given its unique session key |
| UpdateSessionDetails | [UpdateSessionDetailsRequest](#ma-streaming-api-v1-UpdateSessionDetailsRequest) | [UpdateSessionDetailsResponse](#ma-streaming-api-v1-UpdateSessionDetailsResponse) | Update the session details for a session given its unique session key |
## ma/streaming/open_data/v1/open_data.proto
### AxisDataPacket
Values corresponsponding to points on an axis for map parameters
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| axis_identifier | [string](#string) | | Axis identifier |
| timestamp | [fixed64](#fixed64) | | Timestamp |
| values | [ValueArray](#ma-streaming-open_data-v1-ValueArray) | | The data for the axis |
### BoolSample
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| value | [bool](#bool) | | |
| status | [DataStatus](#ma-streaming-open_data-v1-DataStatus) | | |
### BoolSampleList
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| samples | [BoolSample](#ma-streaming-open_data-v1-BoolSample) | repeated | |
### ConfigurationPacket
Data configuration
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| config_id | [string](#string) | | Configuration ID |
| parameter_definitions | [ParameterDefinition](#ma-streaming-open_data-v1-ParameterDefinition) | repeated | The parameter definitions |
| event_definitions | [EventDefinition](#ma-streaming-open_data-v1-EventDefinition) | repeated | The event definitions |
| group_definitions | [GroupDefinition](#ma-streaming-open_data-v1-GroupDefinition) | repeated | The group definitions |
| partial_packet | [bool](#bool) | | Flag to indicate if this packet is part of a larger config. |
| packet_number | [uint32](#uint32) | | The packet number out of the total packets sent if partial packet was set to true. |
| total_packet_number | [uint32](#uint32) | | The total packet number that make up the config id if partial packet was set to true. |
### CoverageCursorInfoPacket
Coverage cursor position for a session has been updated
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data Source name |
| coverage_cursor_time | [fixed64](#fixed64) | | Coverage cursor time (nanoseconds since the UNIX epoch of 1st January 1970, UTC) |
### DataFormatConfigurationPacket
Data format
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format_id | [string](#string) | | Data format ID |
| data_formats | [DataFormatDefinitionPacket](#ma-streaming-open_data-v1-DataFormatDefinitionPacket) | repeated | The data format definitions |
### DataFormatDefinitionPacket
Data Format Definition
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| identifier | [uint64](#uint64) | | Data format identifier |
| type | [DataFormatType](#ma-streaming-open_data-v1-DataFormatType) | | Data format type |
| parameter_identifiers | [ParameterList](#ma-streaming-open_data-v1-ParameterList) | | |
| event_identifier | [string](#string) | | |
### DoubleSample
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| value | [double](#double) | | |
| status | [DataStatus](#ma-streaming-open_data-v1-DataStatus) | | |
### DoubleSampleList
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| samples | [DoubleSample](#ma-streaming-open_data-v1-DoubleSample) | repeated | |
### EndOfSessionPacket
A session has ended
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data Source name |
| topic_partition_offsets | [EndOfSessionPacket.TopicPartitionOffsetsEntry](#ma-streaming-open_data-v1-EndOfSessionPacket-TopicPartitionOffsetsEntry) | repeated | The offsets into each topic / partition (key is topic name, optionally appended with a ':' followed by the partition number) |
### EndOfSessionPacket.TopicPartitionOffsetsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [int64](#int64) | | |
### ErrorPacket
Error Packet
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| error_identifier | [string](#string) | | Error Identifier |
| timestamp | [fixed64](#fixed64) | | Time the error occurred |
| application_name | [string](#string) | | The application containing the error |
| group | [string](#string) | | The error group |
| name | [string](#string) | | The error name |
| description | [string](#string) | | The error description |
| type | [ErrorType](#ma-streaming-open_data-v1-ErrorType) | | The error type |
| status | [ErrorStatus](#ma-streaming-open_data-v1-ErrorStatus) | | The error status |
### EventDataFormat
Desribes the event in this data packet
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format_identifier | [uint64](#uint64) | | |
| event_identifier | [string](#string) | | |
### EventDefinition
Defines the metadata for a given event
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| identifier | [string](#string) | | The full identifier for the event |
| name | [string](#string) | | The name of the event |
| definition_id | [uint32](#uint32) | | A numeric identifier for the event |
| application_name | [string](#string) | | The application containing the event |
| description | [string](#string) | | The event description |
| priority | [EventPriority](#ma-streaming-open_data-v1-EventPriority) | | Event priority |
| groups | [string](#string) | repeated | List of group identifiers in which the event should appear |
| data_types | [DataType](#ma-streaming-open_data-v1-DataType) | repeated | List of native data types for each value |
| format_strings | [string](#string) | repeated | List of format strings, applied to event values for display |
| conversions | [TextConversionDefinition](#ma-streaming-open_data-v1-TextConversionDefinition) | repeated | Text conversion rules to be applied to event values if applicable |
| units | [string](#string) | repeated | List of units applied to event values for display |
### EventPacket
Event
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format | [EventDataFormat](#ma-streaming-open_data-v1-EventDataFormat) | | Data format |
| timestamp | [fixed64](#fixed64) | | Time the event occurred |
| raw_values | [double](#double) | repeated | Raw data (list of doubles, event specific meaning) |
### FormulaDefinition
A formula definition
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| type | [FormulaType](#ma-streaming-open_data-v1-FormulaType) | | Type of formula |
| formula | [string](#string) | | The formula code |
### GroupDefinition
Defines the group
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| identifier | [string](#string) | | The full identifier for the group |
| name | [string](#string) | | The name of the group |
| application_name | [string](#string) | | The applicaion that the group is contained within |
| description | [string](#string) | | Description for the group |
| groups | [GroupDefinition](#ma-streaming-open_data-v1-GroupDefinition) | repeated | Any subgroups nested within the group |
### Int32Sample
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| value | [int32](#int32) | | |
| status | [DataStatus](#ma-streaming-open_data-v1-DataStatus) | | |
### Int32SampleList
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| samples | [Int32Sample](#ma-streaming-open_data-v1-Int32Sample) | repeated | |
### MapDataPacket
Values corresponsponding to the map
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| map_identifier | [string](#string) | | Map identifier |
| timestamp | [fixed64](#fixed64) | | Timestamp |
| x_axis_identifier | [string](#string) | | The identifier of the X axis |
| x_index_identifier | [string](#string) | | The identifier of the X axis index parameter |
| y_axis_identifier | [string](#string) | | The name of the Y axis (only for 2D maps) |
| y_index_identifier | [string](#string) | | The identifier of the Y axis index parameter (only for 2D maps) |
| values | [ValueArray](#ma-streaming-open_data-v1-ValueArray) | repeated | The data for the map |
### MarkerPacket
Marker
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| timestamp | [fixed64](#fixed64) | | Start time of marker |
| end_time | [fixed64](#fixed64) | | End time of marker (optional) |
| label | [string](#string) | | Text label |
| type | [string](#string) | | Type of marker |
| description | [string](#string) | | Text Description |
| source | [string](#string) | | Source |
| value | [int64](#int64) | | Value of the marker if applicable |
### MetadataPacket
General metadata
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| metadata | [MetadataPacket.MetadataEntry](#ma-streaming-open_data-v1-MetadataPacket-MetadataEntry) | repeated | Metadata |
### MetadataPacket.MetadataEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [google.protobuf.Any](https://protobuf.dev/reference/php/api-docs/Google/Protobuf/Any.html) | | |
### NewSessionPacket
New session has started
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data Source name |
| topic_partition_offsets | [NewSessionPacket.TopicPartitionOffsetsEntry](#ma-streaming-open_data-v1-NewSessionPacket-TopicPartitionOffsetsEntry) | repeated | The offsets into each topic / partition (key is topic name, optionally appended with a ':' followed by the partition number) |
| utc_offset | [google.protobuf.Duration](https://protobuf.dev/reference/php/api-docs/Google/Protobuf/Duration.html) | | Difference between UTC time and local standard time in the timezone in which the data is recorded (negative for negative longitudes, positive for positive longitudes) |
| session_info | [SessionInfoPacket](#ma-streaming-open_data-v1-SessionInfoPacket) | optional | Session info |
### NewSessionPacket.TopicPartitionOffsetsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [int64](#int64) | | |
### Packet
Wrapper for all packets
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| type | [string](#string) | | Message type (unique name) |
| session_key | [string](#string) | | Unique session key |
| is_essential | [bool](#bool) | | Is this packet essential? |
| content | [bytes](#bytes) | | Content |
| id | [uint64](#uint64) | | Id (optional if needed by default is 0) |
### ParameterDefinition
Defines the metadata for a given parameter
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| identifier | [string](#string) | | The full identifier for the parameter |
| name | [string](#string) | | The name of the parameter |
| application_name | [string](#string) | | The application containing the parameter |
| description | [string](#string) | | The parameter description |
| groups | [string](#string) | repeated | List of group identifiers in which the parameter should appear |
| units | [string](#string) | | Units that this parameter is measured in |
| data_type | [DataType](#ma-streaming-open_data-v1-DataType) | | Native data type |
| format_string | [string](#string) | | Format strings, applied to sample values for display |
| min_value | [double](#double) | | Minimum value expected for samples of this parameter |
| max_value | [double](#double) | | Maximum value expected for samples of this parameter |
| warning_min_value | [double](#double) | | Threshold minimum value for warnings |
| warning_max_value | [double](#double) | | Threshold maximum value for warnings |
| frequencies | [double](#double) | repeated | Frequencies at which samples of this parameter may be sent |
| includes_row_data | [bool](#bool) | | Whether row data samples may be sent for this parameter |
| includes_synchro_data | [bool](#bool) | | Whether synchro data samples may be sent for this parameter |
| conversion | [TextConversionDefinition](#ma-streaming-open_data-v1-TextConversionDefinition) | | Text conversion rule to be applied if applicable |
| formula | [FormulaDefinition](#ma-streaming-open_data-v1-FormulaDefinition) | | Formula for calculating sample values if applicable |
### ParameterList
List of parameter identifiers
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| parameter_identifiers | [string](#string) | repeated | |
### PeriodicDataPacket
Telemetry samples in periodic format (equally spaced / fixed frequency samples)
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format | [SampleDataFormat](#ma-streaming-open_data-v1-SampleDataFormat) | | Data format |
| start_time | [fixed64](#fixed64) | | Start time (timestamp of first sample) |
| interval | [uint32](#uint32) | | Step / time between samples |
| columns | [SampleColumn](#ma-streaming-open_data-v1-SampleColumn) | repeated | The rest of the Data Each column must have the same no of values |
### RawCANDataPacket
Raw CAN message
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| timestamp | [fixed64](#fixed64) | | Timestamp of the packet |
| bus | [uint32](#uint32) | | CAN Bus |
| can_id | [uint32](#uint32) | | CAN ID |
| payload | [bytes](#bytes) | | Message payload |
| type | [CanType](#ma-streaming-open_data-v1-CanType) | | CAN RxTx |
### RowDataPacket
Telemetry samples in time series format (timestamped rows)
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format | [SampleDataFormat](#ma-streaming-open_data-v1-SampleDataFormat) | | Data format |
| timestamps | [fixed64](#fixed64) | repeated | Timestamps |
| rows | [SampleRow](#ma-streaming-open_data-v1-SampleRow) | repeated | The rest of the Data Each row must have the same no of values = the same as the parameters |
### SampleColumn
"Column" of telemetry sample values
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| double_samples | [DoubleSampleList](#ma-streaming-open_data-v1-DoubleSampleList) | | |
| int32_samples | [Int32SampleList](#ma-streaming-open_data-v1-Int32SampleList) | | |
| bool_samples | [BoolSampleList](#ma-streaming-open_data-v1-BoolSampleList) | | |
| string_samples | [StringSampleList](#ma-streaming-open_data-v1-StringSampleList) | | |
### SampleDataFormat
Desribes the parameters in this data packet
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format_identifier | [uint64](#uint64) | | |
| parameter_identifiers | [ParameterList](#ma-streaming-open_data-v1-ParameterList) | | |
### SampleRow
"Row" of telemetry sample values
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| double_samples | [DoubleSampleList](#ma-streaming-open_data-v1-DoubleSampleList) | | |
| int32_samples | [Int32SampleList](#ma-streaming-open_data-v1-Int32SampleList) | | |
| bool_samples | [BoolSampleList](#ma-streaming-open_data-v1-BoolSampleList) | | |
| string_samples | [StringSampleList](#ma-streaming-open_data-v1-StringSampleList) | | |
### SessionInfoPacket
Session info
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_source | [string](#string) | | Data Source name |
| identifier | [string](#string) | | Identifier |
| type | [string](#string) | | Type |
| version | [uint32](#uint32) | | Version |
| associate_session_keys | [string](#string) | repeated | Associate session keys |
| details | [SessionInfoPacket.DetailsEntry](#ma-streaming-open_data-v1-SessionInfoPacket-DetailsEntry) | repeated | Session details (detail name, detail value) |
### SessionInfoPacket.DetailsEntry
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| key | [string](#string) | | |
| value | [string](#string) | | |
### StringSample
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| value | [string](#string) | | |
| status | [DataStatus](#ma-streaming-open_data-v1-DataStatus) | | |
### StringSampleList
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| samples | [StringSample](#ma-streaming-open_data-v1-StringSample) | repeated | |
### SynchroDataPacket
Telemetry samples in synchro format (variable frequency samples)
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| data_format | [SampleDataFormat](#ma-streaming-open_data-v1-SampleDataFormat) | | Data format |
| start_time | [fixed64](#fixed64) | | Start time (timestamp of first sample) |
| intervals | [uint32](#uint32) | repeated | Step / time between each sample and the previous |
| column | [SampleColumn](#ma-streaming-open_data-v1-SampleColumn) | repeated | The rest of the Data Each column must have number of values = number of intervals + 1 |
### SystemStatusMessage
A system status message
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| service | [string](#string) | | Service to which this message relates |
| data_source | [string](#string) | | Data source name that this service relates to |
| type | [SystemStatusType](#ma-streaming-open_data-v1-SystemStatusType) | | Type of message
Contents......... TBD |
### TextConversionDefinition
A text conversion definition
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| conversion_identifier | [string](#string) | | The conversion rule identifier |
| input_values | [double](#double) | repeated | The values to convert from |
| string_values | [string](#string) | repeated | The strings to convert to |
| default | [string](#string) | | The default string if the input does not match |
### ValueArray
"Array" of values
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| values | [double](#double) | repeated | |
### CanType
CAN type
| Name | Number | Description |
| ---- | ------ | ----------- |
| CAN_TYPE_UNSPECIFIED | 0 | |
| CAN_TYPE_TRANSMIT | 1 | |
| CAN_TYPE_RECEIVE | 2 | |
### DataFormatType
Data format type
| Name | Number | Description |
| ---- | ------ | ----------- |
| DATA_FORMAT_TYPE_UNSPECIFIED | 0 | |
| DATA_FORMAT_TYPE_PARAMETER | 1 | |
| DATA_FORMAT_TYPE_EVENT | 2 | |
### DataStatus
Data status showing if samples are invalid for any reason
| Name | Number | Description |
| ---- | ------ | ----------- |
| DATA_STATUS_UNSPECIFIED | 0 | |
| DATA_STATUS_VALID | 1 | |
| DATA_STATUS_MISSING | 2 | |
| DATA_STATUS_ERROR | 3 | |
### DataType
Native data type
| Name | Number | Description |
| ---- | ------ | ----------- |
| DATA_TYPE_UNSPECIFIED | 0 | Unspecified |
| DATA_TYPE_FLOAT64 | 1 | 64 bit floating point (i.e. “double”) |
| DATA_TYPE_FLOAT32 | 2 | 32 bit floating point |
| DATA_TYPE_UINT32 | 3 | 32 bit unsigned integer |
| DATA_TYPE_SINT32 | 4 | 32 bit signed integer |
| DATA_TYPE_UINT16 | 5 | 16 bit unsigned integer |
| DATA_TYPE_SINT16 | 6 | 16 bit signed integer |
| DATA_TYPE_UINT8 | 7 | 8 bit unsigned integer |
| DATA_TYPE_SINT8 | 8 | 8 bit signed integer |
| DATA_TYPE_STRING | 9 | String |
### ErrorStatus
Error Status
| Name | Number | Description |
| ---- | ------ | ----------- |
| ERROR_STATUS_UNSPECIFIED | 0 | |
| ERROR_STATUS_SET | 1 | |
| ERROR_STATUS_CLEARED | 2 | |
### ErrorType
Error type
| Name | Number | Description |
| ---- | ------ | ----------- |
| ERROR_TYPE_UNSPECIFIED | 0 | |
| ERROR_TYPE_CURRENT | 1 | |
| ERROR_TYPE_LOGGED | 2 | |
### EventPriority
Event priority type
| Name | Number | Description |
| ---- | ------ | ----------- |
| EVENT_PRIORITY_UNSPECIFIED | 0 | |
| EVENT_PRIORITY_CRITICAL | 1 | |
| EVENT_PRIORITY_HIGH | 2 | |
| EVENT_PRIORITY_MEDIUM | 3 | |
| EVENT_PRIORITY_LOW | 4 | |
| EVENT_PRIORITY_DEBUG | 5 | |
### FormulaType
Types of formula. Can be extended to support other languages in the future
| Name | Number | Description |
| ---- | ------ | ----------- |
| FORMULA_TYPE_UNSPECIFIED | 0 | Unspecified |
| FORMULA_TYPE_FDL | 1 | Motion Applied proprietary FDL, used for virtual parameters with System Monitor |
| FORMULA_TYPE_CSHARP | 2 | An open format translated from FDL to C# |
### SystemStatusType
Types of status message
| Name | Number | Description |
| ---- | ------ | ----------- |
| SYSTEM_STATUS_TYPE_UNSPECIFIED | 0 | Unspecified |
| SYSTEM_STATUS_TYPE_HEARTBEAT | 1 | Service is still alive |
| SYSTEM_STATUS_TYPE_STATUS | 2 | Service has a status update |
| SYSTEM_STATUS_TYPE_ERROR | 3 | Service has generated an error |
| SYSTEM_STATUS_TYPE_WARNING | 4 | Service has generated a warning |
| SYSTEM_STATUS_TYPE_CONNECTION | 5 | A source has connected/disconnected |
## ma/streaming/key_generator/v1/key_generator.proto
### GenerateUniqueKeyRequest
Request for generating a unique key
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| type | [KeyType](#ma-streaming-key_generator-v1-KeyType) | | |
### GenerateUniqueKeyResponse
Response to a request for generating a unique key
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| string_key | [string](#string) | | |
| ulong_key | [uint64](#uint64) | | |
### KeyType
The type of key that should be generated
| Name | Number | Description |
| ---- | ------ | ----------- |
| KEY_TYPE_UNSPECIFIED | 0 | |
| KEY_TYPE_ULONG | 1 | |
| KEY_TYPE_STRING | 2 | |
### UniqueKeyGeneratorService
Unique key generator service
| Method Name | Request Type | Response Type | Description |
| ----------- | ------------ | ------------- | ------------|
| GenerateUniqueKey | [GenerateUniqueKeyRequest](#ma-streaming-key_generator-v1-GenerateUniqueKeyRequest) | [GenerateUniqueKeyResponse](#ma-streaming-key_generator-v1-GenerateUniqueKeyResponse) | Generate a unique key which can be used to uniquely identify entities |
## Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
| double | | double | double | float | float64 | double | float | Float |
| float | | float | float | float | float32 | float | float | Float |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
---
# Overview
## Introduction
The Bridge Service decodes a raw stream of quads from an ATLAS Data Server (ADS), converting the data to engineering
values then into the Stream Protocol via the Stream API. It includes components to manage sessions, configuration,
metadata etc.
All RDA protected data will be filtered out at this point, based on the active team license, so any downstream
components will only receive data available to the team.
## Choose your deployment
Bridge Service is the same program in every deployment. What changes is how it is started, and therefore which
configuration file it reads.
| How Bridge Service runs | Configuration file it reads |
|---|---|
| **Launched by ADS** (installed with ADS) | `Documents\McLaren Electronic Systems\ATLAS 9\BridgeService\BridgeServiceConfig.json` |
| **Standalone on Windows** (you run `MA.DataPlatforms.Bridge.Host.exe` yourself) | `Configs\AppConfig.json` next to the exe, or the file you pass with `-c` |
| **Docker** (`atlasplatformdocker/bridge-service-host`) | `/app/Configs/AppConfig.json` in the container, or the file named by the `CONFIG_FILE_PATH` environment variable |
`BridgeServiceConfig.json` and `AppConfig.json` have the same format and accept the same sections, described in the
[Configuration Guide](configuration-guide.md).
=== "Launched by ADS"
On first launch, ADS copies the default `AppConfig.json` from `\BridgeService\Configs\` to
`Documents\McLaren Electronic Systems\ATLAS 9\BridgeService\BridgeServiceConfig.json`. From then on, ADS always
starts Bridge Service with that copy.
- **Edit `BridgeServiceConfig.json`**, not the `AppConfig.json` in the install folder. Once the copy exists, changes
to the install-folder file have no effect.
- To start again from the default file (for example after upgrading ADS), delete `BridgeServiceConfig.json`. ADS
creates a new copy the next time it launches Bridge Service.
- ADS passes its own feed port to Bridge Service, which overrides `BridgeConfig.FeedPort` in the file.
- If `EssentialsConfig` and `RdaConfig` paths are left empty, Bridge Service uses the config, PGV and PUL folders
set in ATLAS 9 for the Windows user running it.
Bridge service uses the name of the ADS as the DataSource name. This can be configured within the ADS on
Setup | General | General Network Settings | Name.
=== "Standalone on Windows"
Run `MA.DataPlatforms.Bridge.Host.exe`. It accepts three optional command-line arguments:
| Argument | Meaning | Example |
|---|---|---|
| `-c` | Configuration file path | `-c "C:\Bridge\MyConfig.json"` |
| `-l` | Log file path (see [Logging](configuration-guide.md#7-serilog-configuration)) | `-l "C:\Logs\bridge.txt"` |
| `-p` | Feed port that ADS connects to | `-p 9697` |
!!! warning "Use an absolute `-c` path, or start from the install folder"
A relative configuration path is resolved from the folder Bridge Service is started from. If you start it from
anywhere else, pass an absolute path with `-c`.
As with ADS, empty `EssentialsConfig` and `RdaConfig` paths fall back to the config, PGV and PUL folders set in
ATLAS 9 for the Windows user running Bridge Service.
=== "Docker"
The image runs from `/app` and reads `/app/Configs/AppConfig.json`. Either mount your own file over it, or mount it
anywhere and set `CONFIG_FILE_PATH` to its absolute path inside the container.
```bash
docker run -p 9697:9697 -p 10011:10011 -v /srv/bridge/AppConfig.json:/app/Configs/AppConfig.json:ro -v /srv/essentials:/essentials:ro atlasplatformdocker/bridge-service-host
```
!!! warning "Settings you must change for Docker"
- **`EssentialsConfig.CfgDirectoryPaths` and `PgvDirectoryPaths` are required.** There is no ATLAS 9 fallback
in a container: if either is empty, Bridge Service stops at startup with
*"DirectoryPaths needs to be specified in EssentialsConfig"*. List the folders as they appear **inside** the
container. If you use PUL files, set `RdaConfig.PulFilesSearchPaths` the same way.
- **`StreamApiConfig.BrokerUrl`**: `localhost` refers to the container itself. Point it at your Kafka broker's
host name.
- **Ports**: publish the feed port (default `9697`) that ADS connects to, and the Prometheus metrics port
(`10011` in the default configuration file).
Any setting can also be overridden with an
[environment variable](configuration-guide.md#overriding-configuration-with-environment-variables), for example
`-e StreamApiConfig__BrokerUrl=kafka:9092`.
## Splitting data across Kafka topics or partitions
The data can be split across multiple Kafka topics or partitions. For more information, refer to
[Stream Creation Strategy](../stream_api/reference_docs/configuration/server-config.md/#stream-creation-strategies).
The examples below show only the two relevant sections.
!!! note "Add or update — don't replace the whole file"
Change these sections in your existing configuration file and leave the other sections in place.
=== "Example with StreamCreationStrategy=2 (Topic based)"
```json title="BridgeServiceConfig.json" linenums="1" hl_lines="3"
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "localhost:9094",
"PartitionMappings": [ {} ],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"BatchingResponses": false
},
"StreamSelectionConfig": {
"Auto": true,
"Mappings": [ {} ]
}
}
```
=== "Example with StreamCreationStrategy=1 (Partition based)"
```json title="BridgeServiceConfig.json" linenums="1" hl_lines="3"
{
"StreamApiConfig": {
"StreamCreationStrategy": 1,
"BrokerUrl": "localhost:9094",
"PartitionMappings": [
{
"Stream": "Stream1",
"Partition": 1
},
{
"Stream": "Stream2",
"Partition": 2
},
{
"Stream": "Stream3",
"Partition": 3
},
{
"Stream": "Stream4",
"Partition": 4
},
{
"Stream": "Stream5",
"Partition": 5
},
{
"Stream": "Stream6",
"Partition": 6
},
{
"Stream": "Stream7",
"Partition": 7
},
{
"Stream": "Stream8",
"Partition": 8
},
{
"Stream": "Stream9",
"Partition": 9
} ],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"BatchingResponses": false
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{
"AppName": "ATLAS",
"Stream": "Stream1"
},
{
"AppName": "FIA",
"Stream": "Stream2"
},
{
"AppName": "Chassis",
"Stream": "Stream3"
},
{
"AppName": "Arbitrator",
"Stream": "Stream4"
},
{
"AppName": "Coordinator",
"Stream": "Stream5"
},
{
"AppName": "Controller",
"Stream": "Stream6"
},
{
"AppName": "Dash",
"Stream": "Stream7"
},
{
"AppName": "BrakeControl",
"Stream": "Stream8"
},
{
"AppName": "TAG320BIOS",
"Stream": "Stream9"
} ]
}
}
```
!!! info "Logs"
From Bridge Service 2.1.1, the default configuration file logs to the console window only, so no log file is
written unless you configure one. See [Logging](configuration-guide.md#7-serilog-configuration).
## Setup
**Prerequisite:**
Kafka broker - The Bridge service needs to be configured to write to a Kafka broker. As you can see in the above example, the config file points to a broker url, which is hosting kafka locally on the same machine as the ADS.
To enable the Bridge Service, set "Enable remote data feed" setting to "True" in ADS | Tools | Options | Recording tab | General

Restart ADS once the setting is applied.
Once the data is published on Kafka, users can use the Stream API to consume the data. For more information, please refer to the [Stream API Sample code](https://github.com/mat-docs/MA.Streaming.Api.UsageSample)
!!! note
Currently, ADS will launch the Bridge Service in a separate command prompt for ease of testing/validation and diagnostics.
## UNIX Timestamps
Timestamps from Motion Applied ECUs are relative to midnight local time. To convert the timestamps to UNIX epoch time in UTC,
the date and the local timezone offset on the machine hosting the bridge service is used.
!!! warning
It also applies to File Telemetry Recorders and Multi-Session Offload Recorders in addition to live telemetry.
Replaying a raw file on a machine that is incorrectly configured could publish timestamps at the incorrect date and
timezone.
---
# Configuration Guide
The MA DataPlatforms Bridge service uses multiple configuration sections to control various aspects of data streaming, processing, and integration. This guide provides comprehensive documentation for all configuration sections.
## Configuration File Structure
The configuration file is `AppConfig.json` when you run Bridge Service yourself (standalone or in Docker), and
`BridgeServiceConfig.json` when ADS launches it. Both have the same format — see
[Choose your deployment](index.md#choose-your-deployment) for which file applies to you. It contains the following
top-level sections:
```json
{
"StreamApiConfig": { ... },
"StreamSelectionConfig": { ... },
"BridgeConfig": { ... },
"EssentialsConfig": { ... },
"RdaConfig": { ... },
"DiskBackedBufferConfig": { ... },
"Serilog": { ... }
}
```
## Overriding Configuration with Environment Variables
Bridge Service loads `AppConfig.json` first, then applies any matching environment variables on
top of it — environment variables take precedence over values in the JSON file. This applies in
both deployment modes (standalone host and ADS-integrated).
Address nested configuration keys with a double underscore (`__`) between each segment:
```powershell
$env:StreamApiConfig__BrokerUrl = "kafka-broker.company.com:9092"
$env:BridgeConfig__DataSource = "RaceTrack01"
```
!!! tip
Use environment variables for values you don't want committed to `AppConfig.json` — for
example broker credentials — instead of writing them into the file.
!!! note
Environment variables are read once at startup. Restart the Bridge Service after changing one.
## 1. StreamApiConfig
Controls the Stream API integration and Kafka broker connectivity.
### Properties
| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `StreamCreationStrategy` | int/enum| 2 | Strategy for creating Kafka topics/streams • `1` = PartitionBased • `2` = TopicBased (recommended) |
| `BrokerUrl` | string | "localhost:9092" | Kafka broker connection string |
| `PartitionMappings` | array | [] | Partition mapping configurations (PartitionBased only) |
| `IntegrateSessionManagement` | boolean | true | Enable session management integration |
| `IntegrateDataFormatManagement`| boolean | true | Enable data format management integration |
| `UseRemoteKeyGenerator` | boolean | false | Use remote key generator service |
| `RemoteKeyGeneratorServiceAddress` | string | "" | URL of remote key generator service |
| `InitialisationTimeoutSeconds` | int | 1 | Timeout in seconds for Stream API init |
| `Domain` | string | "" | Optional domain specification |
| `Security` | object | null | Kafka SASL/SSL credentials — see [Kafka Security (SASL / SSL)](#kafka-security-sasl-ssl) below |
### Example Configuration
```json
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "kafka-broker.company.com:9092",
"PartitionMappings": [],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"InitialisationTimeoutSeconds": 1,
"Domain": "Telemetry"
}
}
```
### Kafka Security (SASL / SSL)
If your Kafka broker requires authentication or an encrypted connection, add a `Security` object
inside `StreamApiConfig`. Security is only activated once you set `SaslUsername`, `SslCaLocation`,
or `SslCertificateLocation` — leave `Security` out entirely to connect without any security, which
is unchanged for existing unsecured deployments.
| Property | Type | Description |
| :--- | :--- | :--- |
| `SaslUsername` | string? | SASL username. Setting this activates security. |
| `SaslPassword` | string? | SASL password. |
| `Protocol` | string? | `Plaintext`, `Ssl`, `SaslPlaintext`, or `SaslSsl`. Defaults to `SaslPlaintext` once security is activated. |
| `Mechanism` | string? | `Plain`, `ScramSha256`, or `ScramSha512`. Defaults to `Plain` once security is activated. |
| `SslCaLocation` | string? | Path to the CA certificate (PEM) used to verify the broker's certificate. |
| `SslCertificateLocation` | string? | Path to the client certificate (PEM), for mutual TLS. Setting this activates security. |
| `SslKeyLocation` | string? | Path to the client private key (PEM), for mutual TLS. |
| `SslKeyPassword` | string? | Password for the client private key, if it's encrypted. |
=== "SASL/PLAIN"
```json title="AppConfig.json" linenums="1" hl_lines="4-7"
{
"StreamApiConfig": {
"BrokerUrl": "kafka-broker.company.com:9094",
"Security": {
"Protocol": "SaslPlaintext",
"Mechanism": "Plain",
"SaslUsername": "myuser",
"SaslPassword": "mypassword"
}
}
}
```
=== "SASL/SCRAM-SHA-512"
```json title="AppConfig.json" linenums="1" hl_lines="4-7"
{
"StreamApiConfig": {
"BrokerUrl": "kafka-broker.company.com:9094",
"Security": {
"Protocol": "SaslPlaintext",
"Mechanism": "ScramSha512",
"SaslUsername": "myuser",
"SaslPassword": "mypassword"
}
}
}
```
=== "SSL (broker certificate only)"
```json title="AppConfig.json" linenums="1" hl_lines="4-6"
{
"StreamApiConfig": {
"BrokerUrl": "kafka-broker.company.com:9094",
"Security": {
"Protocol": "Ssl",
"SslCaLocation": "/certs/ca.pem"
}
}
}
```
=== "SSL (mutual TLS)"
```json title="AppConfig.json" linenums="1" hl_lines="4-8"
{
"StreamApiConfig": {
"BrokerUrl": "kafka-broker.company.com:9094",
"Security": {
"Protocol": "Ssl",
"SslCaLocation": "/certs/ca.pem",
"SslCertificateLocation": "/certs/client-cert.pem",
"SslKeyLocation": "/certs/client-key.pem",
"SslKeyPassword": "keypassword"
}
}
}
```
=== "SASL over TLS"
```json title="AppConfig.json" linenums="1" hl_lines="4-8"
{
"StreamApiConfig": {
"BrokerUrl": "kafka-broker.company.com:9094",
"Security": {
"Protocol": "SaslSsl",
"Mechanism": "ScramSha512",
"SaslUsername": "myuser",
"SaslPassword": "mypassword",
"SslCaLocation": "/certs/ca.pem"
}
}
}
```
!!! tip
Bridge Service also reads [environment variables](#overriding-configuration-with-environment-variables),
so credentials can be supplied without writing them into `AppConfig.json`:
```
StreamApiConfig__Security__SaslUsername=myuser
StreamApiConfig__Security__SaslPassword=mypassword
```
### Stream Creation Strategy Explained
The Bridge service works with Stream API's two streaming strategies. Your choice affects how Bridge streams are mapped to Kafka topics.
#### Topic-Based Strategy (`StreamCreationStrategy = 2`)
Each stream from the Bridge service maps to its own Kafka topic. This is simpler and recommended for most use cases.
**How Mapping Works:**
* Bridge uses `StreamSelectionConfig` to determine stream names.
* Each unique stream name creates a separate Kafka topic.
* **Topic naming:** `{Domain}.Data.{StreamName}`
!!! example "Example Scenario"
**Bridge Configuration:**
```json
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"Domain": "Production"
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "EngineTelemetry" },
{ "AppName": "Chassis*", "Stream": "ChassisTelemetry" },
{ "AppName": "Aero*", "Stream": "AeroTelemetry" }
]
}
}
```
**Resulting Kafka Topics:**
* `Production.Data.EngineTelemetry` (All Engine* app groups)
* `Production.Data.ChassisTelemetry` (All Chassis* app groups)
* `Production.Data.AeroTelemetry` (All Aero* app groups)
**Use Topic-Based When:**
* You have fewer than 100 unique streams.
* You want simple debugging (each stream has its own topic).
* Topic limits are not a concern.
* Message time alignment across streams is not important, or will be handled at the consumer level (note: Kafka does not align messages between topics).
#### Partition-Based Strategy (`StreamCreationStrategy = 1`)
Multiple streams share a single Kafka topic but are distributed across different partitions. Requires explicit partition mappings in `StreamApiConfig`.
**How Mapping Works:**
* Bridge uses `StreamSelectionConfig` to determine stream names.
* Stream API uses `PartitionMappings` to assign each stream to a partition.
* All streams share the same topic: `{Domain}.Data.MainDataSource`.
* **IMPORTANT:** Partition 0 is reserved by Stream API.
!!! example "Example Scenario"
**Bridge Configuration:**
```json
{
"StreamApiConfig": {
"StreamCreationStrategy": 1,
"Domain": "Production",
"PartitionMappings": [
{ "Stream": "EngineTelemetry", "Partition": 1 },
{ "Stream": "ChassisTelemetry", "Partition": 2 },
{ "Stream": "AeroTelemetry", "Partition": 3 },
{ "Stream": "BrakeTelemetry", "Partition": 4 }
]
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "EngineTelemetry" },
{ "AppName": "Chassis*", "Stream": "ChassisTelemetry" },
{ "AppName": "Aero*", "Stream": "AeroTelemetry" },
{ "AppName": "Brake*", "Stream": "BrakeTelemetry" }
]
}
}
```
**Resulting Kafka Topic with Partitions:**
Topic: `Production.Data.MainDataSource`
* Partition 0: [Reserved by Stream API]
* Partition 1: `EngineTelemetry` data
* Partition 2: `ChassisTelemetry` data
* Partition 3: `AeroTelemetry` data
* Partition 4: `BrakeTelemetry` data
!!! danger "Critical Rules for Partition-Based"
1. Stream names in `StreamSelectionConfig` **MUST** match `Stream` in `PartitionMappings`.
2. **Partition 0 is reserved** - all mappings must use partition 1 and above.
3. Each stream must have a unique partition number.
4. Kafka topic must be created with enough partitions (max partition number + 1).
**Use Partition-Based When:**
* You have hundreds or thousands of streams.
* Kafka topic limits are a concern.
* You need better resource utilization.
* You need better resource utilization.
* **You need time-aligned data across multiple streams** - Kafka guarantees message order only within a single partition, so partition-based allows all streams to share one topic with proper temporal alignment.
!!! note "Time-Aligned Data Consideration"
For both Topic-Based and Partition-Based strategies: If you need time-aligned data across multiple application groups, map all of them to a **single stream name** in `StreamSelectionConfig`. This ensures:
* **Topic-Based (Strategy 2):** All data goes to one Kafka topic with aligned timestamps.
* **Partition-Based (Strategy 1):** All data goes to one partition within the topic with aligned timestamps.
**Example for time-aligned data:**
```json
{
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "VehicleTelemetry" },
{ "AppName": "Chassis*", "Stream": "VehicleTelemetry" },
{ "AppName": "Aero*", "Stream": "VehicleTelemetry" },
{ "AppName": "Brake*", "Stream": "VehicleTelemetry" }
]
}
}
```
All application groups now write to the same stream, ensuring temporal alignment in Kafka.
### Stream Mapping Flow
1. **Data arrives** at Bridge with `AppName` (e.g., "EngineData")
2. **`StreamSelectionConfig`** maps `AppName` to **Stream**
* *Example:* "EngineData" -> matches "Engine*" -> "EngineTelemetry"
3. **Stream API** receives "EngineTelemetry" stream
4. **`StreamCreationStrategy`** determines Kafka destination:
* **Topic-Based (Strategy 2):** Writes to Kafka topic `Production.Data.EngineTelemetry`.
* **Partition-Based (Strategy 1):**
* Looks up "EngineTelemetry" in `PartitionMappings`.
* Finds Partition 1.
* Writes to `Production.Data.MainDataSource`, Partition 1.
## 2. StreamSelectionConfig
Controls how data streams are mapped from application groups to Stream API streams, including wildcard pattern matching support.
### Properties
| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `Auto` | boolean | true | Automatically map app names to stream names without transformation |
| `Mappings` | array | [] | Custom mappings from app names to streams with wildcard support (when `Auto=false`) |
### Mappings Structure
Each mapping entry contains:
| Field | Type | Description |
| :--- | :--- | :--- |
| `AppName` | string | Application group name or pattern (supports wildcards: `*`) |
| `Stream` | string | Target stream name in Stream API |
### Wildcard Pattern Matching
The `AppName` field supports wildcard patterns using the `*` character:
* **Exact match:** `"EngineData"` - matches only "EngineData"
* **Prefix match:** `"Engine*"` - matches "EngineData", "EngineTemp", "EnginePressure"
* **Suffix match:** `"*Telemetry"` - matches "EngineTelemetry", "ChassisTelemetry"
* **Contains:** `"*_Data_*"` - matches any app name containing "_Data_"
**Pattern Evaluation Rules:**
1. Patterns are evaluated in order of definition.
2. First matching pattern wins.
3. Case-insensitive matching.
4. Results are cached for performance.
### Example Configurations
#### Auto Mode (Simple)
```json
{
"StreamSelectionConfig": {
"Auto": true
}
}
```
*In Auto mode, each app group streams to its own stream with the same name.*
#### Manual Mapping (No Wildcards)
```json
{
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{
"AppName": "EngineData",
"Stream": "engine-telemetry-stream"
},
{
"AppName": "ChassisData",
"Stream": "chassis-telemetry-stream"
}
]
}
}
```
#### Wildcard Mapping (Flexible)
```json
{
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{
"AppName": "Engine*",
"Stream": "engine-telemetry-stream"
},
{
"AppName": "Chassis*",
"Stream": "chassis-telemetry-stream"
},
{
"AppName": "*Telemetry",
"Stream": "general-telemetry-stream"
},
{
"AppName": "Aero_*_Data",
"Stream": "aerodynamics-stream"
}
]
}
}
```
### Best Practices
1. **Ordering Matters:** Place more specific patterns before general ones.
2. **Auto Mode:** Use when stream names match app group names exactly.
3. **Wildcards:** Use to reduce configuration complexity when dealing with many similar app groups.
## 3. BridgeConfig
Controls core Bridge service behavior including processing units, data handling, and flow control strategies.
### Properties
| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `DataSource` | string | "Default" | Name identifier for the data source |
| `UseStringIdentifier` | boolean | false | Use string-based identifiers instead of numeric IDs |
| `AdsTimeoutInSeconds` | int | 720 | Timeout in seconds for detecting session stop when no data is received from ADS (ATLAS Data Server) |
| `ProcessFlow` | enum | SequentialAll | Data processing flow strategy (see below for details) |
| `FeedPort` | int? | null | Optional port override for the data feed (see [Feed Port and Metric Port Resolution](#feed-port-and-metric-port-resolution)) |
| `MetricPort` | int? | null | Optional port override for the Prometheus metrics endpoint (see [Feed Port and Metric Port Resolution](#feed-port-and-metric-port-resolution)) |
| `LiveConcurrencyFactor` | int | 4 | Number of parallel processing units for live telemetry |
| `OffloadConcurrencyFactor` | int | 12 | Number of parallel processing units for offloaded (historical/replayed) telemetry |
| `OffloadProcessing` | boolean | true | Whether offloaded data is processed at all; when `false`, offloaded data is discarded instead of being written out |
| `OffloadStream` | string | "" (empty) | Optional stream name that offloaded data is routed to, instead of the default stream |
| `StandalonePgvList` | string[] | [] (empty) | PGV app IDs, as decimal or `0x`-prefixed hex strings, that Bridge Service should accept as standalone and output data for (see below) |
### Feed Port and Metric Port Resolution
The feed port (data ingress) and the Prometheus metrics port are each resolved from multiple
sources, in priority order:
1. **Feed port:** the `-p` command-line argument or the `FEED_PORT` environment variable.
2. **Metric port:** the `METRIC_PORT` environment variable (there is no `-m` command-line
argument).
3. `BridgeConfig.FeedPort` / `BridgeConfig.MetricPort` in `AppConfig.json` (or the equivalent
`BridgeConfig__FeedPort` / `BridgeConfig__MetricPort` environment variables described in
[Overriding Configuration with Environment Variables](#overriding-configuration-with-environment-variables)).
4. Built-in defaults: **9697** for the feed port, **10010** for the metric port.
!!! note
`FEED_PORT` and `METRIC_PORT` are read directly by the host process and take priority over
any `BridgeConfig__FeedPort` / `BridgeConfig__MetricPort` value — if a stale `FEED_PORT`
environment variable is set, it silently overrides a `FeedPort` you set in `AppConfig.json`.
### ProcessFlow Strategies
The `ProcessFlow` property controls how the Bridge service handles data flow and backpressure:
#### SequentialAll (Default)
* **Value:** `"SequentialAll"` or `0`
* **Behavior:** Processes all data sequentially without dropping any packets
* **Use when:** Data integrity is critical and you need to ensure every packet is processed
* **Impact:** May experience backpressure if downstream systems are slow
#### DropOldest
* **Value:** `"DropOldest"` or `1`
* **Behavior:** Drops oldest unprocessed data when buffers are full, prioritizing recent data
* **Use when:** Real-time data is more important than historical completeness
* **Impact:** Better performance under load, but some data may be dropped during high traffic
* **Note:** Applies per-session dropping strategy to maintain data freshness
### Example Configuration
```json
{
"BridgeConfig": {
"DataSource": "RaceTrack01",
"UseStringIdentifier": true,
"LiveConcurrencyFactor": 16,
"AdsTimeoutInSeconds": 600,
"ProcessFlow": "SequentialAll"
}
}
```
### Example with DropOldest Flow
```json
{
"BridgeConfig": {
"DataSource": "LiveTelemetry",
"UseStringIdentifier": true,
"LiveConcurrencyFactor": 24,
"AdsTimeoutInSeconds": 720,
"ProcessFlow": "DropOldest"
}
}
```
### Performance Tuning
* **`LiveConcurrencyFactor`**: Controls the number of parallel processing units for live telemetry. Increase for higher throughput on multi-core systems. Higher values use more CPU.
* **`OffloadConcurrencyFactor`**: Controls the number of parallel processing units for offloaded (historical/replayed) telemetry. Increase for higher throughput on multi-core systems. Higher values use more CPU.
* **`OffloadProcessing`**: Set to `false` to discard offloaded data instead of processing it, if offload telemetry isn't needed downstream.
* **`AdsTimeoutInSeconds`**: Controls how long the Bridge waits without receiving data before considering a session stopped. Default is 720 seconds (12 minutes). Reduce for faster session timeout detection, increase if you expect longer gaps in data transmission.
* **`ProcessFlow`**: Choose `SequentialAll` when data completeness is critical, or `DropOldest` when real-time performance is more important than historical completeness.
### Standalone PGV List
`StandalonePgvList` lists the PGV app IDs Bridge Service should accept as standalone. When data
from the ECU requests an app ID that's in this list, Bridge Service loads that PGV and starts
outputting data from that app. If the list is empty, or an app's ID isn't in it, Bridge Service
does not output data from that app.
Each entry is a string, parsed as decimal or (with a `0x`/`0X` prefix) hexadecimal, and must fit
in the range 0-65535. Leading and trailing whitespace is trimmed.
```json title="AppConfig.json" linenums="1"
{
"BridgeConfig": {
"StandalonePgvList": [ "100", "0x64", "0xFF" ]
}
}
```
## 4. EssentialsConfig
Configuration files (CFG) and Parameter Group Values (PGV) are essential for data decoding.
!!! note "Windows: empty paths fall back to ATLAS 9"
On Windows, if `CfgDirectoryPaths` or `PgvDirectoryPaths` is empty, Bridge Service uses the config and PGV folders
set in ATLAS 9 for the Windows user running it. That is why an ADS-launched Bridge Service usually needs no
`EssentialsConfig` section.
!!! warning "Docker / Linux: both paths are required"
There is no ATLAS 9 fallback outside Windows. If `CfgDirectoryPaths` or `PgvDirectoryPaths` is empty, Bridge
Service stops at startup with *"DirectoryPaths needs to be specified in EssentialsConfig"* — even when
`RemoteConfigIndexerUrl` is set.
### Properties
| Property | Type | Description |
| :--- | :--- | :--- |
| `CfgDirectoryPaths` | string[] | Array of directory paths containing CFG configuration files |
| `PgvDirectoryPaths` | string[] | Array of directory paths containing PGV parameter files |
| `RemoteConfigIndexerUrl`| string? | Optional base URL of the Configs service of MA.DataPlatforms.Indexing (see [Using Remote Config Indexer](#using-remote-config-indexer)). Leave it out, or empty, to search the local directories only. |
### Example Configuration
```json
{
"EssentialsConfig": {
"CfgDirectoryPaths": [
"C:\\Data\\Logging\\AutoConfig",
"C:\\Data\\Logging\\ManualConfig"
],
"PgvDirectoryPaths": [
"C:\\Data\\Parameters\\PGVs",
"C:\\SharedConfigs\\PGVs"
],
"RemoteConfigIndexerUrl": null
}
}
```
### Using Remote Config Indexer
Use a remote config indexer when many CFG and PGV files are stored centrally and you want Bridge Service to look up
where a file is instead of searching its own folders.
`RemoteConfigIndexerUrl` must point at the **Configs service** of MA.DataPlatforms.Indexing, which listens on port
**5050** by default. It is not the Files service on port 5000. Give the base URL only, with no path, for example
`http://config-server.company.com:5050`. Bridge Service calls these endpoints on it:
| Endpoint | Used to |
|---|---|
| `GET /api/processing/files/cfg?configId=…` | Find the CFG files for a config ID |
| `GET /api/processing/files/pgv?appId=…&appVersion=…` | Find the PGV files for an app ID and version |
| `GET /api/processing/info?configId=…` | Read the processing info for a config ID |
| `GET /api/heartbeat` | Check the service is available |
When the indexer doesn't return a file, Bridge Service falls back to searching `CfgDirectoryPaths` and
`PgvDirectoryPaths`.
!!! warning "The indexer returns file paths, not file contents"
Bridge Service opens the files itself at the paths the indexer returns, so those paths must be readable from
where Bridge Service runs:
- **Windows**: run the indexer on the same machine, or index network share paths that both machines can reach.
- **Docker**: the paths the indexer reports must exist inside the Bridge Service container. Mount the same
storage at the same path in both.
This works the same whether Bridge Service is launched by ADS, run standalone on Windows, or run in Docker.
```json title="AppConfig.json" linenums="1"
{
"EssentialsConfig": {
"CfgDirectoryPaths": ["C:\\Data\\Configs\\CFG"],
"PgvDirectoryPaths": ["C:\\Data\\Configs\\PGV"],
"RemoteConfigIndexerUrl": "http://config-server.company.com:5050"
}
}
```
## 5. RdaConfig
Reduced Data Access (RDA) configuration for reading telemetry data files.
### Properties
| Property | Type | Description |
| :--- | :--- | :--- |
| `PulFilesSearchPaths` | string[] | Array of directory paths to search for PUL files |
### Example Configuration
```json
{
"RdaConfig": {
"PulFilesSearchPaths": [
"C:\\RDA\\SessionData\\2026",
"C:\\RDA\\Archive",
"\\\\FileServer\\RDA\\Shared"
]
}
}
```
## 6. DiskBackedBufferConfig
Controls the per-session buffer that holds messages pending validation retry. Once a session's
buffer exceeds `MaxQueueLength`, further items spill to disk instead of growing memory
unbounded, and are read back from disk as the queue drains.
### Properties
| Property | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `MaxQueueLength` | int | 1000 | Number of items kept in memory per session before overflow spills to disk |
| `TempFolderPath` | string | `%TEMP%\EngineeringConversion\DiskBackedBuffer` | Directory used to store the disk-backed overflow files |
### Example Configuration
```json title="AppConfig.json" linenums="1"
{
"DiskBackedBufferConfig": {
"MaxQueueLength": 1000
}
}
```
## 7. Serilog Configuration
Bridge Service logging is configured with the `Serilog` section of the configuration file, in the standard
[Serilog JSON settings](https://github.com/serilog/serilog-settings-configuration) format. Bridge Service includes
two sinks: **Console** and **File**.
### Where logs go
| Your configuration file | Where logs go |
|---|---|
| **Has a `Serilog` section** | Only where that section says. `-l` and `LOG_FILE_PATH` are **ignored**. |
| **Has no `Serilog` section** | The console, plus a log file that rolls over daily, at the first of: the path given by `-l` or `LOG_FILE_PATH`; on Windows, `bridge-svc-log.txt` in the ADS log file folder; otherwise `Logs/bridge-svc-log.txt` relative to the folder Bridge Service was started from. |
!!! warning "No log file by default"
From Bridge Service 2.1.1, the default configuration file contains a `Serilog` section that writes to the
**console only**. No log file is written in any deployment — including when ADS launches Bridge Service, because
the log path ADS passes with `-l` is ignored while a `Serilog` section is present. To get a log file, either:
- add a File sink to the `Serilog` section (see [Write logs to a file](#write-logs-to-a-file)), or
- delete the `Serilog` section, so the fallback locations in the table above apply. When launched by ADS, this
writes `BridgeLog.txt` to the ADS log file folder.
### Write logs to a file
Add a File sink next to the Console sink. Use an absolute path: a relative path is resolved from the folder Bridge
Service was started from, which for an ADS-launched Bridge Service is its install folder and may not be writable.
```json title="AppConfig.json" linenums="1" hl_lines="8-15"
{
"Serilog": {
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{ "Name": "Console" },
{
"Name": "File",
"Args": {
"path": "C:\\Logs\\Bridge\\bridge-svc-log.txt",
"rollingInterval": "Day",
"outputTemplate": "[{Timestamp:HH:mm:ss.fff} {Level:u3}]: {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
```
With `"rollingInterval": "Day"`, the date is added to the file name, for example `bridge-svc-log20261014.txt`. The
File sink also accepts the standard `retainedFileCountLimit` and `fileSizeLimitBytes` arguments to limit disk use.
!!! note "Docker"
Console output appears in `docker logs`. If you add a File sink, write to a path on a mounted volume, for example
`"path": "/logs/bridge-svc-log.txt"` with `-v /srv/bridge-logs:/logs`. Otherwise the log file is lost when the
container is removed.
### Log Levels
Set `MinimumLevel.Default` to one of:
* **Verbose:** Very detailed, trace-level information.
* **Debug:** Debugging information.
* **Information:** General informational messages (recommended default).
* **Warning:** Warnings that don't stop operation.
* **Error:** Errors and exceptions.
* **Fatal:** Critical failures causing shutdown.
You can also change the level without editing the file, with an
[environment variable](#overriding-configuration-with-environment-variables):
`Serilog__MinimumLevel__Default=Debug`.
## Complete Configuration Example
```json
{
"StreamApiConfig": {
"StreamCreationStrategy": 2,
"BrokerUrl": "kafka-prod.company.com:9094",
"PartitionMappings": [],
"IntegrateSessionManagement": true,
"IntegrateDataFormatManagement": true,
"UseRemoteKeyGenerator": false,
"RemoteKeyGeneratorServiceAddress": "",
"InitialisationTimeoutSeconds": 1,
"Domain": "motorsport"
},
"StreamSelectionConfig": {
"Auto": false,
"Mappings": [
{ "AppName": "Engine*", "Stream": "engine-telemetry" },
{ "AppName": "Chassis*", "Stream": "chassis-telemetry" },
{ "AppName": "Aero*", "Stream": "aerodynamics-telemetry" },
{ "AppName": "*Telemetry", "Stream": "general-telemetry" }
]
},
"BridgeConfig": {
"DataSource": "TestTrack_Simulator",
"UseStringIdentifier": true,
"LiveConcurrencyFactor": 16,
"OffloadConcurrencyFactor": 8,
"AdsTimeoutInSeconds": 600,
"ProcessFlow": "SequentialAll"
},
"EssentialsConfig": {
"CfgDirectoryPaths": [
"C:\\ProgramData\\ATLAS\\Configs",
"\\\\FileServer\\SharedConfigs\\CFG"
],
"PgvDirectoryPaths": [
"C:\\ProgramData\\ATLAS\\Parameters",
"\\\\FileServer\\SharedConfigs\\PGV"
],
"RemoteConfigIndexerUrl": null
},
"RdaConfig": {
"PulFilesSearchPaths": [
"C:\\RDA\\Sessions\\2026",
"\\\\FileServer\\RDA\\Archive"
]
},
"DiskBackedBufferConfig": {
"MaxQueueLength": 1000
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext}: {Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "C:\\Logs\\bridge-service-.txt",
"rollingInterval": "Day",
"retainedFileCountLimit": 30,
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss}] [{Level:u3}] {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
```
## Troubleshooting
### Common Configuration Issues
* **Issue: Stream API fails to initialize**
* Check `BrokerUrl` is correct and accessible.
* Verify Kafka broker is running.
* Increase `InitialisationTimeoutSeconds`.
* **Issue: Data not decoding correctly**
* Verify CFG files exist in `CfgDirectoryPaths`.
* Check PGV files are present in `PgvDirectoryPaths`.
* **Issue: Stream mapping not working**
* Verify `Auto` is set to `false` when using custom mappings.
* Check wildcard patterns/order.
* **Issue: Performance problems**
* Increase `LiveConcurrencyFactor` / `OffloadConcurrencyFactor`.
* Consider using `ProcessFlow: "DropOldest"` if real-time data is more important than completeness.
* **Issue: Data is being dropped**
* Check if `ProcessFlow` is set to `"DropOldest"`. This is the expected behavior when buffers are full.
* If data completeness is critical, change to `"SequentialAll"`.
* Alternatively, increase `LiveConcurrencyFactor` and `OffloadConcurrencyFactor` to improve throughput.
* **Issue: Session stops prematurely or doesn't stop**
* Adjust `AdsTimeoutInSeconds` based on your data streaming pattern.
* Default (720 seconds / 12 minutes) works for most scenarios.
* Reduce for faster timeout detection in live scenarios.
* Increase if you have legitimate gaps in data transmission.
* **Issue: Remote Config Indexer not working**
* Verify `RemoteConfigIndexerUrl` is the base URL of the indexer's **Configs** service (port 5050 by default), not the Files service, and has no path.
* Check network connectivity to the config server, for example by opening `/api/heartbeat`.
* Ensure the configuration indexer service is running.
* Check that the file paths the indexer returns are readable from where Bridge Service runs — in Docker, inside the container.
* Add local `CfgDirectoryPaths` and `PgvDirectoryPaths` as backup.
* **Issue: Bridge Service stops at startup with "DirectoryPaths needs to be specified in EssentialsConfig"**
* Outside Windows (for example in Docker) there is no ATLAS 9 fallback: set both `CfgDirectoryPaths` and `PgvDirectoryPaths`, using paths inside the container.
* On Windows, set them in `EssentialsConfig`, or set the config and PGV folders in ATLAS 9 for the Windows user running Bridge Service.
* **Issue: No Bridge Service log file is written**
* If the configuration file has a `Serilog` section, `-l` and `LOG_FILE_PATH` are ignored. Add a File sink to the `Serilog` section, or delete the section — see [Where logs go](#where-logs-go).
* **Issue: Changes to `AppConfig.json` have no effect when ADS launches Bridge Service**
* ADS uses `Documents\McLaren Electronic Systems\ATLAS 9\BridgeService\BridgeServiceConfig.json` instead. Edit that file — see [Choose your deployment](index.md#choose-your-deployment).
* **Issue: Stream API fails to connect with a SASL/SSL handshake error**
* Verify `Protocol` and `Mechanism` match what the broker is actually configured for.
* For SASL, double-check `SaslUsername`/`SaslPassword`.
* For SSL, verify certificate paths (`SslCaLocation`, `SslCertificateLocation`, `SslKeyLocation`) are correct and readable by the account running Bridge Service.
* Remember `Security` only activates once `SaslUsername`, `SslCaLocation`, or `SslCertificateLocation` is set — an incomplete `Security` block may silently connect unsecured instead of failing.
* **Issue: Environment variable override isn't applied**
* Confirm the key uses `__` (double underscore) between each nested segment, e.g. `BridgeConfig__DataSource`.
* Environment variables are only read at startup — restart the Bridge Service after changing one.
* **Issue: Bridge Service fails to start after adding `StandalonePgvList`**
* Each entry must be a plain decimal number or a `0x`/`0X`-prefixed hex number, and fit in the range 0-65535.
* Remove or fix any entry that isn't one of those two formats.
!!! warning "Resource Requirements"
Increasing these values requires more system resources (CPU and memory). Setting values too high on smaller machines may lead to deadlock or threadpool starvation. **Recommended settings for an 8-core machine with 16GB RAM:**
- `LiveConcurrencyFactor`: 12
- `OffloadConcurrencyFactor`: 24
---
# Overview
Broadcast Service gives your live telemetry feed highly-available replication to multiple
downstream consumers, so a downstream restart, network blip, or slow consumer never costs you
data — every downstream tracks its own place in the stream and catches up independently once it
reconnects.
It sits between an upstream source and one or more downstream consumers. Towards its upstream
source, it exposes the same ADS messages, so from the
source's point of view it looks like an ordinary downstream. Towards its own downstreams, it acts
as the upstream — replaying that same ADS messages — so each downstream can consume,
fall behind, and recover without affecting the others.
!!! note "Not the same as Bridge Service"
Broadcast Service is a separate product from [the Bridge Service](../bridge_service/index.md),
which decodes ATLAS quads from an ADS into Stream API packets. Broadcast Service does not
decode anything — it replicates an ADS messages (which may originate
from an ADS, or another Broadcast Service) to more places, with durable
replay if a downstream falls behind. If you're looking for quad decoding, see the Bridge
Service docs instead.
## Before you start
At minimum, every deployment needs:
- **An inbound feed port** — the port Broadcast Service listens on for the upstream
ADS source (`FeedPort`).
- **At least one downstream Bridge target** — Broadcast Service refuses to start if no targets
are configured.
- **A write-ahead log (WAL) directory** — where incoming records are durably persisted so
targets can replay them (`Wal.Directory`).
- **Enough disk for the WAL** — durability comes from disk. Plan capacity around your WAL
segment size and how far behind your slowest target is allowed to fall before it's caught up
again.
## At a glance
| | |
|---|---|
| **Default feed port** | `9697` |
| **Default metrics port** | `10010` |
| **Default WAL directory** | `./wal` |
| **Config file** | `AppConfig.json` (override the path with the `CONFIG_FILE_PATH` environment variable) |
## Two ways to run it
The same binary runs either way — there's no separate "standalone" build versus an "integrated"
one:
- **`dotnet run`** — run the host project (or published binaries) directly. It reads
`Configs/AppConfig.json` next to the executable by default.
- **Docker** — the shipped `Dockerfile` exposes the feed port (9697) and metrics port (10010).
Supply configuration via a mounted config file plus `CONFIG_FILE_PATH`, or via
`BroadcastConfig__...` environment variables.
See [Getting Started](getting-started.md) for step-by-step instructions for both.
## Next steps
- [Getting Started](getting-started.md) — run your first instance and confirm it's forwarding data.
- [Configuration Guide](configuration-guide.md) — task-by-task guidance for adding targets,
tuning the WAL, and overriding config with environment variables.
- [Configuration Reference](configuration-reference.md) — the full field-by-field reference for
`AppConfig.json`.
- [Troubleshooting](troubleshooting.md) — diagnosing startup failures, unhealthy targets, and
disk growth.
---
# Getting Started
This walks through running a first Broadcast Service instance with the smallest config that
starts successfully, and confirming it's forwarding data.
Pick the tab for how you want to run it — each one is self-contained.
=== "dotnet run"
**Prerequisites**
- .NET 8.0 runtime available on the machine.
- At least one reachable downstream Bridge endpoint.
- An upstream source such as ADS or another Broadcast Service to
point at the feed port once Broadcast Service is running.
**Minimal config**
Save this next to the host executable as `Configs/AppConfig.json` (or point
`CONFIG_FILE_PATH` at it):
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"FeedPort": 9697,
"MetricPort": 10010,
"Wal": {
"Directory": "./wal"
},
"Targets": {
"BridgeConfigs": [
{
"Name": "downstream-bridge",
"Host": "downstream-host",
"Port": 9697
}
]
}
}
}
```
This configures the inbound feed port, the metrics port, the WAL directory, and a single
Bridge target to forward to. `Targets.BridgeConfigs` needs at least one entry — Broadcast
Service won't start with zero targets configured.
**Start it**
```bash
dotnet run MA.DataPlatforms.Bridge.Broadcast.Host.exe
```
**Confirm it's working**
Open `http://localhost:10010/metrics` (using the `MetricPort` from your config) and look for
the `broadcast_target_up` gauge with a `target` label matching your target's name — it reads
`1` once that target has connected successfully. Point your upstream source at the feed port
(`9697` by default) and confirm `broadcast_ingest_total` is increasing as records arrive.
**First-run problems**
- **Startup fails with `Invalid broadcast configuration: ...`** — configuration validation
failed. The message lists every problem found, joined together. Common causes: `FeedPort`
outside 1-65535, no targets configured, two targets with the same name, or a target missing
`Host`.
- **Feed port already in use** — if another process (including a second Broadcast Service
instance) is already bound to `FeedPort`, startup fails. Pick a different `FeedPort` or
stop the conflicting process.
- **WAL directory not writable** — if the process account can't create or write files under
`Wal.Directory`, the service can't persist incoming records. Check the path exists and is
writable by whichever account is running the process.
=== "Docker"
**Prerequisites**
- Docker (or a compatible container runtime).
- At least one reachable downstream Bridge endpoint.
- An upstream source such as ADS or another Broadcast Service to
point at the feed port once Broadcast Service is running.
**Minimal config**
No config file is baked into the image. Mount one in, or supply the same values as
environment variables. As a file, mounted at (for example) `/config/AppConfig.json`:
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"FeedPort": 9697,
"MetricPort": 10010,
"Wal": {
"Directory": "/data/wal"
},
"Targets": {
"BridgeConfigs": [
{
"Name": "downstream-bridge",
"Host": "downstream-host",
"Port": 9697
}
]
}
}
}
```
!!! warning "Mount a volume for the WAL directory"
Mount a volume at whatever path you set `Wal.Directory` to — `/data/wal` in the example
above. If that path isn't backed by a mounted volume, the WAL — and everything not yet
replayed to every target — is lost when the container is recreated.
**Start it**
```bash
docker run \
-p 9697:9697 -p 10010:10010 \
-e CONFIG_FILE_PATH=/config/AppConfig.json \
-v /host/path/config:/config \
-v /host/path/wal:/data/wal \
atlasplatformdocker/broadcast-service-host:latest
```
**Confirm it's working**
Open `http://localhost:10010/metrics` on the host (mapped from the container's `MetricPort`)
and look for the `broadcast_target_up` gauge with a `target` label matching your target's
name — it reads `1` once that target has connected successfully.
**First-run problems**
- **Startup fails with `Invalid broadcast configuration: ...`** — same validation as above:
check `FeedPort` range, that at least one target is configured, target names are unique,
and required target fields (`Host`/`Port`) are set.
- **Feed port already in use** — make sure the host port you mapped to 9697 isn't already
taken by another container or process.
- **WAL directory not writable / disappears on restart** — if `/data/wal` (or wherever
`Wal.Directory` points) isn't backed by a mounted volume, or the mount isn't writable by
the container's process, the service can't persist records, or loses everything on
container recreation.
---
# Configuration Guide
Task-by-task guidance for the changes you're most likely to make to `AppConfig.json`. For the
full field-by-field list, defaults, and validation rules, see the
[Configuration Reference](configuration-reference.md).
## I want to add a downstream Bridge target
**Situation**: you want Broadcast Service to forward the feed on to another Bridge
endpoint — replicating bridge-to-bridge.
Add an entry to `Targets.BridgeConfigs`:
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"Targets": {
"BridgeConfigs": [
{
"Name": "site-b-bridge",
"Host": "site-b-bridge.internal",
"Port": 9697
}
]
}
}
}
```
`Host` is required — the target won't validate without one. `Port` defaults to `9697` if
omitted. Broadcast Service connects to this target at `http://{Host}:{Port}`.
**Result**: on connect, this target performs a licence handshake with the downstream and replays
any cached session-control history, then forwards live records over gRPC. If the
target's queue fills (it's capped at `QueueCapacity`, default `100000`), Broadcast Service
blocks and waits rather than dropping records for a Bridge target — the target must catch up on
its own.
**When to use**: any time the downstream is itself a Bridge consumer.
## I want to run more than one target
**Situation**: fan-out replication — for example, two Bridge targets at different sites.
Add multiple entries to `BridgeConfigs`. Every target needs a unique `Name` (case-insensitive);
startup fails otherwise. `Host`/`Port` aren't part of the effective name, so give each target a
distinct `Name` explicitly even if they point at different hosts.
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"Targets": {
"BridgeConfigs": [
{ "Name": "site-a-bridge", "Host": "site-a.internal", "Port": 9697 },
{ "Name": "site-b-bridge", "Host": "site-b.internal", "Port": 9697 }
]
}
}
}
```
**When to use**: whenever you need the same feed replicated to more than one place — each target
maintains its own replay cursor, so a slow or disconnected target never affects the others.
## I want to control whether a target receives offload (bulk historical) data
**Situation**: some downstreams should only see live telemetry, not the bulk historical data a
source sends during an offload.
Set `OffloadProcessing` on the target:
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"Targets": {
"BridgeConfigs": [
{
"Name": "live-only-bridge",
"Host": "site-c.internal",
"Port": 9697,
"OffloadProcessing": false
}
]
}
}
}
```
`OffloadProcessing` defaults to `false` on every target. With it `false`, offload records are
not forwarded to that target — by design, not as a failure — though the target's replay cursor
still advances past them. Session-control records are always forwarded regardless of this
setting. Set it to `true` if that target should also receive the bulk historical data.
**When to use**: set to `true` for targets that need the full historical record (for example, an
archive), and leave `false` (the default) for targets that only care about live data.
## I want to tune WAL segment size or compaction behavior
**Situation**: you're seeing more disk usage on the WAL directory than expected, or want to
change how often compaction runs.
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"Wal": {
"Directory": "./wal",
"CompactionEnabled": true,
"CompactionIntervalMs": 5000,
"SegmentRollBytes": 10485760
}
}
}
```
- `SegmentRollBytes` (default `10485760`, i.e. 10 MiB, minimum `1024`) controls how large each
WAL segment file grows before a new one is started.
- `CompactionEnabled` (default `true`) turns segment trimming on or off. If disabled, no
segments are ever removed.
- `CompactionIntervalMs` (default `5000`, minimum `100`, only checked when compaction is
enabled) controls how often compaction runs.
Compaction only removes a sealed segment once **every** target's replay cursor has passed it —
see [Disk usage growing unexpectedly](troubleshooting.md#disk-usage-growing-unexpectedly-on-the-wal-directory)
for what happens when one target lags behind. The full field list, including `FsyncOnFlush` and
`OffsetFlushIntervalMs`, is in the [Configuration Reference](configuration-reference.md).
**When to use**: increase `SegmentRollBytes` to reduce the number of segment files under
high-throughput feeds; tighten `CompactionIntervalMs` if you need disk space reclaimed sooner
after targets catch up.
## I want to override config with environment variables instead of editing AppConfig.json
**Situation**: you don't want a value (or don't want to redeploy a file) to change
`AppConfig.json` directly — for example, per-environment overrides in a deployment pipeline.
Broadcast Service loads `AppConfig.json` first, then applies matching environment variables on
top — environment variables win. Address nested keys with a double underscore (`__`) between
each segment:
```bash
BroadcastConfig__FeedPort=9697
BroadcastConfig__Wal__Directory=/data/wal
```
This is standard .NET configuration layering (`AddJsonFile` then `AddEnvironmentVariables`), so
it applies to any nested object in the config — not just the examples above.
!!! tip
Environment variables are read once at startup. Restart the service after changing one.
**When to use**: containerized or pipeline-driven deployments where you want to keep
`AppConfig.json` generic and inject environment-specific values (like the WAL path or feed port)
at deploy time.
---
# Configuration Reference
Field-by-field reference for the `BroadcastConfig` section of `AppConfig.json`. For task-based
how-tos (adding a target, tuning WAL compaction, and so on), see the
[Configuration Guide](configuration-guide.md).
## Structure
```json title="AppConfig.json" linenums="1"
{
"BroadcastConfig": {
"FeedPort": 9697,
"MetricPort": 10010,
"Wal": { ... },
"Targets": {
"BridgeConfigs": [ ... ]
}
}
}
```
| Property | Type | Default | Notes |
|---|---|---|---|
| `FeedPort` | int | `9697` | Inbound `RemoteDataFeed` gRPC server port. Validated 1-65535. |
| `MetricPort` | int | `10010` | Prometheus metrics port. Not validated; a bind failure is caught and logged as a warning at startup — the service continues without metrics. |
| `Wal` | object | — | Write-ahead log settings. See [Wal](#wal). |
| `Targets` | object | — | Downstream Bridge targets. See [Targets](#targets). |
## Wal
`BroadcastConfig.Wal`.
| Property | Type | Default | Notes |
|---|---|---|---|
| `Directory` | string | `"./wal"` | Data WAL root. The control WAL is written to `{Directory}/control`; per-target cursor offsets are persisted to `{Directory}/offsets.json`. |
| `FsyncOnFlush` | bool | `true` | Applies to both the data and control WAL. |
| `CompactionEnabled` | bool | `true` | If `false`, no WAL segment trimming occurs. |
| `CompactionIntervalMs` | int | `5000` | Validated minimum `100`, only enforced when `CompactionEnabled` is `true`. |
| `SegmentRollBytes` | long | `10485760` (10 MiB) | Validated minimum `1024`. |
| `OffsetFlushIntervalMs` | int | `1000` | Validated minimum `50`. Controls how often per-target cursor offsets are flushed to disk. |
!!! warning
`FsyncOnFlush` is mission-critical for durability. Do not disable it in production —
doing so trades data-loss protection for throughput.
## Targets
`BroadcastConfig.Targets`.
| Property | Type | Default | Notes |
|---|---|---|---|
| `BridgeConfigs` | array of bridge target objects | `[]` | Downstream targets reached over `RemoteDataFeed` gRPC. See [Bridge targets](#bridge-targets). |
At least one entry must be configured in `BridgeConfigs`.
### Shared target fields
Every entry in `BridgeConfigs` accepts these fields in addition to its own type-specific fields
below:
| Property | Type | Default | Notes |
|---|---|---|---|
| `Name` | string | `""` | Display/tracking name for the target. |
| `QueueCapacity` | int | `100000` | Validated minimum `1`. |
| `OffloadProcessing` | bool | `false` | When `false`, offload (bulk historical) telemetry is dropped for this target and its cursor still advances; session control records are always forwarded regardless of this setting. |
| `Retry` | object | — | Reconnect/backoff behavior. See [Retry](#retry). |
The effective name used for uniqueness checks (see [Validation](#validation)) is `Name`.
### Bridge targets
Additional fields for entries in `Targets.BridgeConfigs`:
| Property | Type | Default | Notes |
|---|---|---|---|
| `Host` | string | `""` | Required — an empty host fails validation. |
| `Port` | int | `9697` | Validated 1-65535. |
The target address is built as `http://{Host}:{Port}`.
```json title="AppConfig.json" linenums="1"
{
"Name": "DownstreamBridge01",
"Host": "bridge01.internal",
"Port": 9697,
"QueueCapacity": 500000,
"OffloadProcessing": false,
"Retry": {
"InitialDelayMs": 500,
"MaxDelayMs": 30000,
"JitterMs": 250
}
}
```
## Retry
Each target's `Retry` object (`RetryConfig`).
| Property | Type | Default |
|---|---|---|
| `InitialDelayMs` | int | `500` |
| `MaxDelayMs` | int | `30000` |
| `JitterMs` | int | `250` |
Reconnect backoff is calculated as:
`delay = min(InitialDelayMs * 2^attempt, MaxDelayMs) + random(0, JitterMs)`
The attempt exponent is capped at 30. Retries are unbounded — a target can remain down
indefinitely without affecting the other targets. `InitialDelayMs` and `JitterMs` must each be
`>= 0`, and `MaxDelayMs` must be `>= InitialDelayMs`.
## Validation
Broadcast Service validates `BroadcastConfig` at startup. If any of the following rules are
violated, the service fails to start with an exception of the form
`Invalid broadcast configuration: ; ; ...` (all violated rules are joined by
`; ` into a single message):
- `FeedPort` must be between 1 and 65535.
- At least one target must be configured in `Targets.BridgeConfigs`.
- If `Wal.CompactionEnabled` is `true`, `Wal.CompactionIntervalMs` must be `>= 100`.
- `Wal.OffsetFlushIntervalMs` must be `>= 50` (checked regardless of `CompactionEnabled`).
- `Wal.SegmentRollBytes` must be `>= 1024`.
- Every target must have a non-empty `Name`, and names must be unique case-insensitively across
all targets.
- Every target's `QueueCapacity` must be `>= 1`.
- Every target's `Host` must be non-empty, and `Port` must be between 1 and 65535.
## Environment variable overrides
Broadcast Service loads `AppConfig.json` first, then applies environment variables on top —
environment variables win over values in the JSON file. Address nested keys with a double
underscore (`__`) between each segment, for example:
```
BroadcastConfig__FeedPort=9697
BroadcastConfig__Wal__Directory=/data/wal
```
---
# Troubleshooting
## Service fails to start with "Invalid broadcast configuration: ..."
**Symptom**: the process exits at startup with an error beginning `Invalid broadcast
configuration:`, followed by one or more problems joined together.
**Cause**: configuration validation runs before anything else starts, and rejects the whole
config if it finds a problem — an out-of-range `FeedPort`, zero targets configured, two targets
with the same effective name, a target missing `Host`/`Port`, or a WAL setting below its minimum.
See
[Validation](configuration-reference.md#validation) in the Configuration Reference for the
complete, exact list of rules and valid ranges.
**Fix**: read every problem listed in the error message (they're all reported together, joined
by `; `) and correct each one in `AppConfig.json` or your environment variable overrides against
the rules linked above.
## Metrics endpoint not reachable
**Symptom**: `http://localhost:/metrics` doesn't respond, but the service otherwise
appears to be running and forwarding data.
**Cause**: `MetricPort` isn't validated at startup, and a failure to bind the metrics endpoint
(for example, the port is already in use) is caught and logged as a warning rather than crashing
the process. The service keeps running — and keeps replicating — without a working metrics
endpoint.
**Fix**: check the service's logs for the bind warning to see why the metrics port failed to
bind (commonly, something else is already listening on it), free up the port or change
`MetricPort`, and restart. This is not a sign the replication path itself is broken — check
`broadcast_target_up` and `broadcast_ingest_total` are what you actually care about once metrics
are reachable again.
## A target never goes healthy / `broadcast_target_up` stays 0
**Symptom**: the `broadcast_target_up` gauge for a given `target` label stays at `0` and never
flips to `1`.
**Cause**: the target's connection attempts are failing (unreachable `Host`/`Port`). Retries for
a target are unbounded — a target can be down indefinitely without affecting any other target —
and back off exponentially: each retry waits `min(InitialDelayMs * 2^attempt, MaxDelayMs)` plus a
small random jitter (up to `JitterMs`), so retries get progressively less frequent up to
`MaxDelayMs` (default `30000` ms).
**Fix**: check the service's logs for connection/reconnection errors for that target's name, and
confirm the target's `Host`/`Port` is actually reachable from where Broadcast Service is running.
Once the target does connect, `broadcast_target_up` flips to `1` and `broadcast_reconnect_total`
records how many reconnect attempts it took.
## Offload (bulk historical) data isn't reaching a target
**Symptom**: live telemetry arrives at a target fine, but the bulk historical data sent during an
offload never shows up there.
**Cause**: this is expected, not a bug, if that target has `OffloadProcessing: false` (the
default). With `OffloadProcessing` set to `false`, offload records are deliberately not
forwarded to that target — its replay cursor still advances past them as if they'd been sent, so
it won't try to re-fetch them later. Session-control records are unaffected and are always
forwarded.
**Fix**: set `OffloadProcessing: true` on that target if it should also receive offload data. See
[I want to control whether a target receives offload data](configuration-guide.md#i-want-to-control-whether-a-target-receives-offload-bulk-historical-data)
in the Configuration Guide.
## Disk usage growing unexpectedly on the WAL directory
**Symptom**: the WAL directory keeps growing and doesn't shrink, even with compaction enabled.
**Cause**: compaction only removes a sealed WAL segment once **every** configured target's
replay cursor has advanced past it. A single stalled, disconnected, or very slow target holds
compaction back for every other target too — the WAL has to keep everything that target might
still need to replay.
**Fix**: check `broadcast_target_up` and `broadcast_cursor_gsn` per target to find which one is
lagging or down, and fix or remove that target (see [A target never goes healthy](#a-target-never-goes-healthy-broadcast_target_up-stays-0)
above). If a target is permanently gone and won't come back, removing it from
`Targets.BridgeConfigs` lets compaction proceed for the ones that remain.
Confirm `Wal.CompactionEnabled` is `true` and `Wal.CompactionIntervalMs` is set to a reasonable
value — if `CompactionEnabled` is `false`, no segments are ever removed regardless of target
state.
---
# Overview
## Overview
The MA DataPlatforms Streaming Support Library is a .NET library designed to facilitate real-time and historical data streaming for telemetry and data analysis applications. The library provides a modular architecture for session management, data format handling, packet reading/writing, data buffering, merging, and interpolation.
## Key Features
- **Session Management**: Create, track, and manage live and historical sessions with metadata and associations
- **Data Format Management**: Define and manage parameter and event data formats with automatic ID generation
- **Packet Reading/Writing**: Stream packets to and from Kafka brokers with support for live and historical data
- **Essential Packet Reading**: Efficiently read configuration and metadata packets without full data processing
- **Buffering & Merging**: Buffer incoming data packets, merge them, and extract time-aligned samples
- **Interpolation**: Subscribe to parameters at custom frequencies with automatic super-sampling or sub-sampling
- **Event-Driven Architecture**: Rich event system for tracking session lifecycle, data availability, and processing status
- **Kafka Integration**: Built-in support for Kafka-based streaming with configurable retry policies, [secured (SASL/SSL) brokers, and broker tuning](kafka-configuration.md)
- **Prometheus Metrics**: Built-in monitoring and metrics support
## Architecture
The library follows a modular, pipeline-based architecture where data flows through independent but interconnected modules:

### Module Dependencies
**Independent Core Modules:**
- **Session Manager**: No dependencies on other modules
- **Data Format Manager**: No dependencies on other modules
**Dependent Modules:**
- **Writer Module**: Uses Session Manager and Data Format Manager APIs
- **Reader Module**: Can use Session Manager and Data Format Manager for context
- **Essentials Module**: Lightweight reader for essential/configuration packets only
- **Sample Reader (Buffering)**: Pipelines with Reader Module
- **Data Reader (Interpolation)**: Pipelines with Sample Reader Module
## API Response Format
All APIs in the Support Library return responses in a **consistent, standardized format** using the `ApiResult` pattern. This ensures predictable error handling and makes the library easier to use.
### ApiResult Pattern
Every API call returns an `ApiResult` object with the following structure:
```csharp
public class ApiResult
{
public bool Success { get; } // Indicates if operation succeeded
public T? Data { get; } // Contains the result data if successful
public string Message { get; } // Contains success/error message details
}
```
### Best Practices for Handling API Responses
#### 1. Always Check Success Status
```csharp
var result = sessionService.CreateNewSession(sessionDto);
if (result.Success && result.Data != null)
{
// Use result.Data safely
var sessionInfo = result.Data;
Console.WriteLine($"Session created: {sessionInfo.SessionKey}");
}
else
{
// Handle error
Console.WriteLine($"Failed to create session: {result.Message}");
}
```
#### 2. Null-Safe Data Access
Even when `Success` is `true`, always check that `Data` is not null before accessing it:
```csharp
var formatResult = dataFormatService.GetParameterDataFormatId("source", parameters);
if (formatResult.Success && formatResult.Data != null)
{
var formatId = formatResult.Data.DataFormatId;
// Use formatId safely
}
```
#### 3. Centralized Error Handling
For applications with multiple API calls, consider creating a helper method:
```csharp
public static bool TryGetData(ApiResult result, out T data, Action? onError = null)
{
if (result.Success && result.Data != null)
{
data = result.Data;
return true;
}
onError?.Invoke(result.Message ?? "Unknown error");
data = default!;
return false;
}
// Usage
if (TryGetData(sessionResult, out var sessionInfo, error => _logger.LogError(error)))
{
// Work with sessionInfo safely
ProcessSession(sessionInfo);
}
```
#### 4. Pattern Matching (C# 8.0+)
Use pattern matching for cleaner code:
```csharp
var result = dataFormatService.GetEventDataFormatId("source", "EventName");
var message = result switch
{
{ Success: true, Data: not null } => $"Format ID: {result.Data.DataFormatId}",
{ Success: false } => $"Error: {result.Message}",
_ => "Unexpected result state"
};
```
### Common Response Types
- **Service Creation**: `ApiResult`, `ApiResult`, `ApiResult`, `ApiResult`, `ApiResult`
- **Session Operations**: `ApiResult`, `ApiResult>`
- **Data Format Operations**: `ApiResult`, `ApiResult`
- **Writer Operations**: `ApiResult`
### Note on Subscription Methods
Some operations like `Subscribe()` and `Unsubscribe()` in the Buffering and Interpolation modules return `bool` directly rather than `ApiResult`, for simpler synchronous operations.
This consistent pattern across all modules ensures:
- **Predictable error handling** throughout your application
- **Type safety** with compile-time checks
- **Clear success/failure states** without exceptions for expected failures
- **Detailed messages** for troubleshooting through the `Message` property
## Getting Started
### Installation
```bash
# Install the NuGet package (when available)
dotnet add package MA.DataPlatforms.Streaming.Support.Lib.Core
```
### Prerequisites
- .NET 8.0 or later
- Kafka broker (configured and accessible)
- Prometheus (optional, for metrics)
## Pipeline Initialization Best Practices
When using the reading pipeline (Reader → Buffering → Interpolation), **always start services from the innermost module outward** to prevent data loss due to timing issues.
### ⚠️ Critical: Startup Order
Initialization can be done in any order, but **starting services must follow this order** to ensure downstream modules are ready to receive data before upstream modules start producing it:
```
1. Interpolation Module (Data Reader) ← START FIRST (innermost)
2. Buffering Module (Sample Reader) ← START SECOND
3. Reader Module (Packet Reader) ← START LAST (begins reading)
```
### Why Startup Order Matters
If you start in the wrong order (Reader → Buffering → Interpolation):
- ❌ Reader starts receiving packets from Kafka
- ❌ Buffering module is not started yet → **Packets are dropped**
- ❌ Interpolation module is not subscribed → **Data is lost**
If you start in the correct order (Interpolation → Buffering → Reader):
- ✅ Interpolation module is started and subscribed
- ✅ Buffering module is started and ready to receive
- ✅ Reader starts receiving packets → **All data is captured**
### Complete Pipeline Initialization Example
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Abstractions;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts;
// Assume supportLibApi is already initialized and started
// Create all services (order doesn't matter for creation)
var dataReaderApi = supportLibApi.GetDataReaderApi();
var dataReaderService = dataReaderApi.CreateService().Data;
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
var bufferingConfig = new BufferingConfiguration(["Param1", "Param2", "Param3"]);
var sampleReaderService = sampleReaderApi.CreateService(bufferingConfig).Data;
var readerApi = supportLibApi.GetReadingPacketApi();
var readerService = readerApi.CreateService("MyDataSource","Session_Key").Data;
// Initialize all services (order doesn't matter for initialization)
dataReaderService.Initialise();
sampleReaderService.Initialise();
readerService.Initialise();
// Subscribe to parameters at custom frequency
dataReaderService.Subscribe(
subscriptionKey: "MySubscription",
parameterIdentifiers: new[] { "Param1", "Param2", "Param3" },
subscriptionFrequencyHz: 100, // 100 Hz subscription
handler:new MyBatchResultHandler() );
// START in correct order: INNERMOST to OUTERMOST (CRITICAL!)
// Step 1: Start Interpolation Module FIRST
dataReaderService.Start();
// Step 2: Start Buffering Module SECOND
sampleReaderService.Start();
// Step 3: Start Reader Module LAST
readerService.Start();
```
### Quick Reference
| Phase | Order | Modules |
|-------|-------|---------|
| **Creation** | Any order | Can create in any sequence |
| **Initialization** | Any order | Can initialize in any sequence |
| **Startup** | Inside → Out | Interpolation → Buffering → Reader ⚠️ |
| **Shutdown** | Outside → In | Reader → Buffering → Interpolation |
### Common Mistake Example
```csharp
// ❌ WRONG - Will lose data!
var reader = readerApi.CreateService(config).Data;
reader.Initialise();
reader.Start(); // Started reading!
var buffering = sampleReaderApi.CreateService(config).Data;
buffering.Initialise();
buffering.Start(); // Too late - already missing packets!
var interpolation = dataReaderApi.CreateService().Data;
interpolation.Initialise();
interpolation.Start(); // Too late - already lost data!
```
```csharp
// ✅ CORRECT - No data loss
// Create and initialize all (any order)
var interpolation = dataReaderApi.CreateService().Data;
var buffering = sampleReaderApi.CreateService(config).Data;
var reader = readerApi.CreateService(config).Data;
interpolation.Initialise();
buffering.Initialise();
reader.Initialise();
// Start in correct order: inside-out
interpolation.Start();
interpolation.Subscribe(...); // Ready to receive
buffering.Start();
buffering.Subscribe(...); // Ready to receive
reader.Start(); // Now start reading - pipeline is ready!
```
### Basic Usage
#### 1. Initialize the Support Library
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Abstractions;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Shared;
using MA.Streaming.Abstraction;
using MA.Streaming.Core.Configs;
var logger = new ConsoleLogger();
// Configure Kafka connection using Stream API Configuration
var streamApiConfig = new StreamingApiConfiguration(
StreamCreationStrategy.PartitionBased,
"localhost:9094",
[]);
// To connect to a secured (SASL/SSL) broker or tune the Kafka
// producer/consumer, see the Kafka Configuration page.
// Create the support library API with retry policy (the retry policy used for when the broker not available)
var supportLibApi = new SupportLibApiFactory().Create(
logger,
streamApiConfig,
new RetryPolicy(10, TimeSpan.FromSeconds(5), RetryMode.Finite));
// Subscribe to initialization event
supportLibApi.Initialised += (sender, time) => {
Console.WriteLine($"Library initialized at {time}");
};
// Initialize asynchronously
var cts = new CancellationTokenSource();
await supportLibApi.InitialiseAsync(cts.Token);
// Start the library
if (supportLibApi.IsInitialised)
{
supportLibApi.Start();
}
```
#### 2. Create a Session
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.SessionInfoModule;
// Get the session manager API
var sessionManagerApi = supportLibApi.GetSessionManagerApi();
var sessionService = sessionManagerApi.CreateService().Data;
sessionService.Initialise();
sessionService.Start();
// Create a new session
var sessionResult = sessionService.CreateNewSession(
new SessionCreationDto(
dataSource: "MyDataSource",
identifier: "TestSession001",
type: "session",
version: 1,
utcOffset: TimeSpan.Zero,
details: new[] {
new SessionDetailDto("Location", "LabA"),
new SessionDetailDto("OperatorId", "OP_123")
}));
if (sessionResult.Success && sessionResult.Data != null)
{
var sessionKey = sessionResult.Data.SessionKey;
Console.WriteLine($"Created session: {sessionKey}");
}
```
#### 3. Define Data Formats
```csharp
// Get the data format manager API
var dataFormatApi = supportLibApi.GetDataFormatManagerApi();
var dataFormatService = dataFormatApi.CreateService().Data;
dataFormatService.Initialise();
dataFormatService.Start();
// Define parameter format
var paramResult = dataFormatService.GetParameterDataFormatId(
"MyDataSource",
new[] { "Param1", "Param2", "Param3" });
if (paramResult.Success && paramResult.Data != null)
{
var formatId = paramResult.Data.DataFormatId;
Console.WriteLine($"Parameter format ID: {formatId}");
}
// Define event format
var eventResult = dataFormatService.GetEventDataFormatId(
"MyDataSource",
"LapCompleted");
```
#### 4. Write Data
```csharp
// Get the writer API
var writerApi = supportLibApi.GetWritingPacketApi();
var writerService = writerApi.CreateService().Data;
writerService.Initialise();
writerService.Start();
// Write packet data
writerService.WriteData(
dataSource: "MyDataSource",
stream: "MainStream",
sessionKey: "Session_Key",
packet: new Packet());
```
#### 5. Read Data
!!! note
You will need to spin / wait on the main thread as the Reader Service reads packets or the application will exit.
For example: while(true) { await Task.Delay(1000); }
See [Reader Module](reader-module.md) for a more complete example including handling session start / completion events.
```csharp
// Get the reader API
var readerApi = supportLibApi.GetReadingPacketApi();
var readerService = readerApi.CreateService("MyDataSource", sessionKey).Data;
// Create a handler for received packets
public class MyPacketHandler : IHandler
{
public void Handle(IReceivedPacketDto packet)
{
Console.WriteLine($"Received packet: {packet.Packet.Type}");
}
}
readerService.AddHandler(new MyPacketHandler());
readerService.Initialise();
readerService.Start();
```
#### 6. Buffer and Extract Samples
```csharp
// Get the sample reader API
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
// Configure buffering
var bufferingConfig = new BufferingConfiguration(
subscribedParameters: new[] { "Param1", "Param2" },
bufferingWindowLength: 3000, // 3 seconds
slidingWindowPercentage: 5);
var sampleReaderService = sampleReaderApi.CreateService(bufferingConfig).Data;
// Create a timestamp handler
public class MyTimestampHandler : IHandler
{
public void Handle(ITimestampData data)
{
foreach (var column in data.TimeColumns)
{
Console.WriteLine($"Parameter: {column.Identifier}, Values: {column.SampleValues.Count}");
}
}
}
sampleReaderService.SetReaderService(readerService);
sampleReaderService.AddHandler(new MyTimestampHandler());
sampleReaderService.Initialise();
sampleReaderService.Start();
```
#### 7. Subscribe to Interpolated Data
```csharp
// Get the data reader API (interpolation)
var dataReaderApi = supportLibApi.GetDataReaderApi();
var dataReaderService = dataReaderApi.CreateService().Data;
// Create a batch result handler
public class MyBatchResultHandler : IBatchResultHandler
{
public void Handle(BatchResult result)
{
Console.WriteLine($"Received {result.Results.Count} interpolated samples");
}
}
// Set the sample reader as the data source
dataReaderService.SetSampleReaderService(sampleReaderService);
// Subscribe to parameters at 10 Hz
dataReaderService.Subscribe(
subscriptionKey: "MySubscription",
parameterIdentifiers: new[] { "Param1", "Param2", "Param3" },
subscriptionFrequencyHz: 10.0,
handler: new MyBatchResultHandler(),
deliveryFrequencyHz: 5.0); // Deliver results every 5 Hz
dataReaderService.Initialise();
dataReaderService.Start();
```
## Quick Links
- [Session Manager Module](session-manager.md)
- [Data Format Manager Module](data-format-manager.md)
- [Writer Module](writer-module.md)
- [Reader Module](reader-module.md)
- [Essentials Module](essentials-module.md)
- [Buffering Module](buffering-module.md)
- [Interpolation Module](interpolation-module.md)
- [API Reference](api-reference.md)
## Use Cases
The library supports various data streaming scenarios:
- **Live Session Monitoring**: Stream data from live sessions and process in real-time
- **Historical Playback**: Read and analyze complete historical sessions
- **On-the-Fly Subscription**: Dynamically subscribe to parameters during a live session
- **Data Analysis**: Buffer, merge, and interpolate data for analysis applications
- **Multi-Session Association**: Link related sessions using session GUIDs
## Support
For issues or questions, please send email to atlas10@motionapplied.com
---
# Session Manager
## Overview
The Session Manager Module is one of the two independent core modules in the Support Library. It provides session lifecycle management, including session creation, metadata management, session associations, and real-time notifications for session state changes.
## Key Features
- **Session Creation**: Create new sessions with custom metadata and identifiers
- **Session Lifecycle**: Track live sessions from creation to completion
- **Metadata Management**: Attach and update custom key-value details to sessions
- **Session Associations**: Link related sessions (e.g., linking multiple data collection sessions)
- **Real-time Events**: Subscribe to session lifecycle events
- **Historical Sessions**: Mark sessions as complete and maintain session history
- **Session Querying**: Retrieve all sessions or specific session information
## API Access
### Get the Session Manager API
```csharp
var sessionManagerApi = supportLibApi.GetSessionManagerApi();
```
### Create a Service Instance
```csharp
var serviceResult = sessionManagerApi.CreateService();
if (serviceResult.Success && serviceResult.Data != null)
{
var sessionService = serviceResult.Data;
// Initialize and start the service
sessionService.Initialise();
sessionService.Start();
}
```
## Core Concepts
### Session Information
Each session contains:
- **SessionKey**: Unique identifier for the session (auto-generated)
- **DataSource**: The data source name (e.g., car identifier, system name)
- **Identifier**: User-defined session identifier
- **Type**: Session type (e.g., "session", "virtual", "vtag")
- **Version**: Session version number
- **Historical**: Boolean indicating if session is complete
- **UtcOffset**: Time zone offset for the session
- **Details**: Dictionary of custom metadata (key-value pairs)
- **AssociateSessionKeys**: List of associated session keys
### Session States
Sessions can be in one of two states:
1. **Live Session**: Currently active, `Historical = false`
2. **Historical Session**: Completed session, `Historical = true`
## Methods
### CreateNewSession
Creates a new session with specified metadata.
```csharp
public ApiResult CreateNewSession(SessionCreationDto createSessionDto)
```
**Parameters:**
```csharp
var sessionDto = new SessionCreationDto(
dataSource: "DataSource_A", // Required: Data source identifier
identifier: "Session_001", // Optional: Session identifier
type: "Session", // Optional: Session type (Session, VirtualSession, VTS)
version: 1, // Optional: Version number (default: 1)
utcOffset: TimeSpan.FromHours(1), // Optional: UTC offset (default: local)
details: new[] { // Optional: Custom metadata
new SessionDetailDto("Location", "BuildingB"),
new SessionDetailDto("Equipment", "Sensor_v2"),
new SessionDetailDto("Operator", "User_42")
},
associatedSessionKeys: new[] { // Optional: Related session GUIDs
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
);
var result = sessionService.CreateNewSession(sessionDto);
```
**Example:**
```csharp
var result = sessionService.CreateNewSession(
new SessionCreationDto(
dataSource: "DataSourceX",
identifier: Guid.NewGuid().ToString(),
type: "VirtualSession",
version: 1,
details: new[] {
new SessionDetailDto("CollectionId", "C12345"),
new SessionDetailDto("BatchNumber", "B789")
}
));
if (result.Success && result.Data != null)
{
var sessionKey = result.Data.SessionKey;
Console.WriteLine($"Session created: {sessionKey}");
}
```
### GetSessionInfo
Retrieves detailed information about a specific session.
```csharp
public ApiResult GetSessionInfo(string dataSource, string sessionKey)
```
**Example:**
```csharp
var result = sessionService.GetSessionInfo("MyDataSource", sessionKey);
if (result.Success && result.Data != null)
{
var session = result.Data;
Console.WriteLine($"Session: {session.Identifier}");
Console.WriteLine($"Type: {session.Type}");
Console.WriteLine($"Historical: {session.Historical}");
Console.WriteLine($"Details: {session.Details.Count}");
}
```
### GetAllSessions
Retrieves all sessions from the broker.
```csharp
public ApiResult> GetAllSessions()
```
**Example:**
```csharp
var result = sessionService.GetAllSessions();
if (result.Success && result.Data != null)
{
Console.WriteLine($"Found {result.Data.Count} sessions");
foreach (var session in result.Data)
{
Console.WriteLine($"- {session.SessionKey}: {session.Identifier} ({session.Type})");
}
}
```
### UpdateIdentifier
Updates the session identifier.
```csharp
public ApiResult UpdateIdentifier(
string dataSource,
string sessionKey,
string newIdentifier)
```
**Example:**
```csharp
var result = sessionService.UpdateIdentifier(
"MyDataSource",
sessionKey,
"UpdatedSessionIdentifier_001");
if (result.Success && result.Data != null)
{
Console.WriteLine($"Updated identifier: {result.Data.Identifier}");
}
```
### UpdateSessionDetails
Adds or updates session metadata details.
```csharp
public ApiResult UpdateSessionDetails(
string dataSource,
string sessionKey,
IReadOnlyList sessionDetails)
```
**Example:**
```csharp
var newDetails = new[] {
new SessionDetailDto("LapCount", "45"),
new SessionDetailDto("BestLapTime", "1:32.456")
};
var result = sessionService.UpdateSessionDetails(
"MyDataSource",
sessionKey,
newDetails);
if (result.Success && result.Data != null)
{
Console.WriteLine($"Session now has {result.Data.Details.Count} details");
}
```
**Note**: Details with existing keys are updated; new keys are added.
### AddAssociateSession
Links another session as an associate.
```csharp
public ApiResult AddAssociateSession(
string dataSource,
string sessionKey,
string addingAssociateKey)
```
**Example:**
```csharp
// Create an associate session
var associateResult = sessionService.CreateNewSession(
new SessionCreationDto(
dataSource: "MyDataSource",
identifier: "AssociateSession",
type: "Data"
));
if (associateResult.Success && associateResult.Data != null)
{
var associateKey = associateResult.Data.SessionKey;
// Link it to the main session
var linkResult = sessionService.AddAssociateSession(
"MyDataSource",
mainSessionKey,
associateKey);
if (linkResult.Success && linkResult.Data != null)
{
Console.WriteLine($"Associated sessions: {linkResult.Data.AssociateSessionKeys.Count}");
}
}
```
### EndSession
Marks a session as historical (completed).
```csharp
public ApiResult EndSession(string dataSource, string sessionKey)
```
**Example:**
```csharp
var result = sessionService.EndSession("MyDataSource", sessionKey);
if (result.Success && result.Data != null)
{
Console.WriteLine($"Session ended. Historical: {result.Data.Historical}");
}
```
**Important**: Once a session is marked as historical, it should not be modified.
## Events
The Session Manager provides four events for tracking session lifecycle.
**Important - Forward-Only Event Notifications**: All events are **only triggered for actions that occur after the session manager has started**. Events will not fire for sessions or changes that existed before the session manager was initialized. This means:
- No replay of existing sessions or state when you subscribe
- Only new changes happening after startup will trigger events
- To retrieve existing sessions, use the `GetAllSessions()` method
**Event Scope**:
- `LiveSessionStarted`, `LiveSessionStateChange`, `LiveSessionEnded`: Only triggered for live sessions (where `Historical = false`)
- `NewAssociationDetected`: Can be triggered for both live and historical sessions
### LiveSessionStarted
Fired when a new live session is detected or created after the session manager has started.
```csharp
sessionService.LiveSessionStarted += (sender, sessionInfo) =>
{
Console.WriteLine($"Live session started: {sessionInfo.SessionKey}");
Console.WriteLine($"Data Source: {sessionInfo.DataSource}");
Console.WriteLine($"Identifier: {sessionInfo.Identifier}");
};
```
**Note**: Only triggered for live sessions created or detected after session manager startup. Pre-existing live sessions will not trigger this event.
### LiveSessionStateChange
Fired when a live session's state is updated (e.g., details changed, identifier updated) after the session manager has started.
```csharp
sessionService.LiveSessionStateChange += (sender, sessionInfo) =>
{
Console.WriteLine($"Live session state changed: {sessionInfo.SessionKey}");
Console.WriteLine($"Details count: {sessionInfo.Details.Count}");
};
```
**Note**: Only triggered for state changes occurring after session manager startup. Does not fire for historical sessions.
### LiveSessionEnded
Fired when a live session is marked as historical (transitioned from live to completed) after the session manager has started.
```csharp
sessionService.LiveSessionEnded += (sender, sessionInfo) =>
{
Console.WriteLine($"Live session ended: {sessionInfo.SessionKey}");
Console.WriteLine($"Final identifier: {sessionInfo.Identifier}");
Console.WriteLine($"Now historical: {sessionInfo.Historical}"); // Will be true
};
```
**Note**: Triggered during the transition from live to historical that occurs after session manager startup. Once a session is historical, no further live session events are triggered for it.
### NewAssociationDetected
Fired when a session association is created between sessions after the session manager has started.
```csharp
sessionService.NewAssociationDetected += (sender, associationInfo) =>
{
Console.WriteLine($"New association detected:");
Console.WriteLine($" Main: {associationInfo.MainSessionInfo.SessionKey}");
Console.WriteLine($" Associate: {associationInfo.AssociateSessionInfo.SessionKey}");
};
```
**Note**: Can be triggered for both live and historical sessions, but **only for associations created after the session manager has started**. Pre-existing associations will not trigger this event.
## Complete Example
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.SessionInfoModule;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.SessionInfoModule.Abstractions;
public class SessionManagerExample
{
private readonly ISessionManagementService sessionService;
public SessionManagerExample(ISupportLibApi supportLibApi)
{
var sessionApi = supportLibApi.GetSessionManagerApi();
this.sessionService = sessionApi.CreateService().Data;
// Subscribe to events
this.sessionService.LiveSessionStarted += OnLiveSessionStarted;
this.sessionService.LiveSessionStateChange += OnSessionStateChange;
this.sessionService.LiveSessionEnded += OnSessionEnded;
this.sessionService.NewAssociationDetected += OnAssociationDetected;
// Initialize and start
this.sessionService.Initialise();
this.sessionService.Start();
}
public string CreateAndManageSession()
{
// Create session
var createResult = sessionService.CreateNewSession(
new SessionCreationDto(
dataSource: "TestCar",
identifier: "Test_Run_001",
type: "Testing",
version: 1,
details: new[] {
new SessionDetailDto("Driver", "TestDriver"),
new SessionDetailDto("Track", "TestTrack")
}));
if (!createResult.Success || createResult.Data == null)
{
Console.WriteLine($"Failed to create session: {createResult.Message}");
return null;
}
var sessionKey = createResult.Data.SessionKey;
// Update session details
sessionService.UpdateSessionDetails(
"TestCar",
sessionKey,
new[] { new SessionDetailDto("Status", "InProgress") });
// Create and link associate session
var associateResult = sessionService.CreateNewSession(
new SessionCreationDto(
dataSource: "TestCar",
identifier: "Associated_Data",
type: "Telemetry"));
if (associateResult.Success && associateResult.Data != null)
{
sessionService.AddAssociateSession(
"TestCar",
sessionKey,
associateResult.Data.SessionKey);
}
// Later... end the session
sessionService.EndSession("TestCar", sessionKey);
return sessionKey;
}
private void OnLiveSessionStarted(object sender, ISessionInfo session)
{
Console.WriteLine($"[Event] Live session started: {session.SessionKey}");
}
private void OnSessionStateChange(object sender, ISessionInfo session)
{
Console.WriteLine($"[Event] Session state changed: {session.SessionKey}");
}
private void OnSessionEnded(object sender, ISessionInfo session)
{
Console.WriteLine($"[Event] Session ended: {session.SessionKey}");
}
private void OnAssociationDetected(object sender, ISessionAssociationInfo info)
{
Console.WriteLine($"[Event] Association: {info.MainSessionInfo.SessionKey} <-> {info.AssociateSessionInfo.SessionKey}");
}
}
```
## Best Practices
1. **Always Check Results**: All methods return `ApiResult` - always check the `Success` property and handle errors appropriately.
2. **Subscribe to Events Early**: Subscribe to events before calling `Start()` to ensure you don't miss any notifications.
3. **Handle Session Lifecycle**: Use the event system to track when sessions start and end for proper resource management.
4. **Store Session Keys**: Keep track of session keys for later reference, as they're needed for most operations.
5. **End Sessions Properly**: Always call `EndSession()` when a session is complete to mark it as historical.
6. **Use Details for Metadata**: Store important session metadata in details for easy retrieval and filtering.
## Error Handling
```csharp
var result = sessionService.CreateNewSession(sessionDto);
if (!result.Success)
{
Console.WriteLine($"Error: {result.Message}");
// Handle the error appropriately
return;
}
if (result.Data == null)
{
Console.WriteLine("Error: No data returned despite success");
return;
}
// Proceed with the session
var sessionKey = result.Data.SessionKey;
```
## See Also
- [Data Format Manager Module](data-format-manager.md)
- [Writer Module](writer-module.md)
- [Reader Module](reader-module.md)
- [API Reference](api-reference.md)
---
# Data Format Manager
## Overview
The Data Format Manager Module is the second independent core module in the Support Library. It manages data format definitions for parameters and events, automatically generating and caching unique format IDs. This module is essential for defining the structure of data before it can be streamed.
## Key Features
- **Parameter Format Management**: Define parameter groups with automatic ID generation
- **Event Format Management**: Define event types with unique IDs
- **Automatic ID Generation**: Consistent, deterministic ID generation based on content
- **Format Caching**: Efficient retrieval of previously defined formats
- **Data Source Isolation**: Separate format spaces per data source
- **Real-time Notifications**: Events when new formats are detected
- **Format Querying**: Retrieve all formats for a data source or specific format details
## API Access
### Get the Data Format Manager API
```csharp
var dataFormatApi = supportLibApi.GetDataFormatManagerApi();
```
### Create a Service Instance
```csharp
var serviceResult = dataFormatApi.CreateService();
if (serviceResult.Success && serviceResult.Data != null)
{
var dataFormatService = serviceResult.Data;
// Initialize and start the service
dataFormatService.Initialise();
dataFormatService.Start();
}
```
## Core Concepts
### Data Format Types
The module manages two types of data formats:
1. **Parameters**: Groups of parameters (e.g., `["Param1", "Param2", "Param3"]`)
2. **Events**: Single event identifiers (e.g., `"EventA"`, `"EventB"`)
### Data Format Information
Each format definition contains:
- **DataFormatId**: Unique identifier (ulong) for the format
- **DataSource**: The data source this format belongs to
- **Key**: Derived identifier string
- **Identifiers**: List of parameter names or event name
- **DataFormatInfoType**: Type (Parameters or Event)
### Format ID Generation
Format IDs are generated deterministically based on:
- Data source name
- Parameter names (for parameters)
- Format type (parameter group vs. event)
This ensures the same format always gets the same ID, enabling efficient caching and lookup.
## Methods
### GetParameterDataFormatId
Gets or creates a parameter format definition for a group of parameters.
```csharp
public ApiResult GetParameterDataFormatId(
string dataSource,
IReadOnlyList parameterList)
```
**Parameters:**
- `dataSource`: The data source identifier
- `parameterList`: List of parameter names in the group
**Returns:**
- `ParameterDataFormatInfo` containing:
- `DataFormatId`: Unique ID for this parameter group
- `ParameterList`: The list of parameters
**Example:**
```csharp
var result = dataFormatService.GetParameterDataFormatId(
"DataSourceA",
new[] { "Param1", "Param2", "Param3", "Param4" });
if (result.Success && result.Data != null)
{
var formatId = result.Data.DataFormatId;
var parameters = result.Data.ParameterList;
Console.WriteLine($"Parameter Format ID: {formatId}");
Console.WriteLine($"Parameters: {string.Join(", ", parameters)}");
}
```
### GetParametersList
Retrieves the parameter list for a given format ID.
```csharp
public ApiResult GetParametersList(
string dataSource,
ulong dataFormatId)
```
**Example:**
```csharp
var result = dataFormatService.GetParametersList("DataSourceA", formatId);
if (result.Success && result.Data != null)
{
Console.WriteLine($"Parameters in format {formatId}:");
foreach (var param in result.Data.ParameterList)
{
Console.WriteLine($" - {param}");
}
}
```
### GetEventDataFormatId
Gets or creates an event format definition.
```csharp
public ApiResult GetEventDataFormatId(
string dataSource,
string eventName)
```
**Parameters:**
- `dataSource`: The data source identifier
- `eventName`: The event identifier/name
**Returns:**
- `EventDataFormatInfo` containing:
- `DataFormatId`: Unique ID for this event
- `EventName`: The event name
**Example:**
```csharp
var result = dataFormatService.GetEventDataFormatId("DataSourceA", "EventTypeA");
if (result.Success && result.Data != null)
{
var eventFormatId = result.Data.DataFormatId;
var eventName = result.Data.EventName;
Console.WriteLine($"Event '{eventName}' has ID: {eventFormatId}");
}
```
### GetEvent
Retrieves event information for a given format ID.
```csharp
public ApiResult GetEvent(
string dataSource,
ulong dataFormatId)
```
**Example:**
```csharp
var result = dataFormatService.GetEvent("DataSourceA", eventFormatId);
if (result.Success && result.Data != null)
{
Console.WriteLine($"Event format {dataFormatId}: {result.Data.EventName}");
}
```
### GetDataSourceDataFormatInfo
Retrieves all data format definitions for a data source.
```csharp
public ApiResult?> GetDataSourceDataFormatInfo(
string dataSource)
```
**Example:**
```csharp
var result = dataFormatService.GetDataSourceDataFormatInfo("DataSourceA");
if (result.Success && result.Data != null)
{
Console.WriteLine($"Found {result.Data.Count} data formats for DataSourceA:");
foreach (var format in result.Data)
{
Console.WriteLine($" Format IDs: {string.Join(",",format.DataFormats)}");
Console.WriteLine($" Type: {format.DataFormatInfoType}");
Console.WriteLine($" Identifiers: {string.Join(", ", format.Identifiers)}");
}
}
```
## Events
### DataFormatInfoUpdated
Fired when a new data format is created or an existing format is detected.
```csharp
dataFormatService.DataFormatInfoUpdated += (sender, dataFormatInfo) =>
{
Console.WriteLine($"Data format updated:");
Console.WriteLine($" Data Source: {dataFormatInfo.DataSource}");
Console.WriteLine($" Format IDs: {string.Join(",", dataFormatInfo.DataFormats)}");
Console.WriteLine($" Type: {dataFormatInfo.DataFormatInfoType}");
Console.WriteLine($" Identifiers: {string.Join(", ", dataFormatInfo.Identifiers)}");
};
```
**Event Data (`DataFormatInfo`):**
- `DataSource`: The data source identifier
- `DataFormatId`: The unique format ID
- `Key`: The format key
- `Identifiers`: List of parameter names or event name
- `DataFormatInfoType`: Either `DataFormatInfoType.Parameters` or `DataFormatInfoType.Event`
## Complete Example
```csharp
public class DataFormatManagerExample
{
private readonly IDataFormatManagementService dataFormatService;
public DataFormatManagerExample(ISupportLibApi supportLibApi)
{
var dataFormatApi = supportLibApi.GetDataFormatManagerApi();
this.dataFormatService = dataFormatApi.CreateService().Data;
// Subscribe to events
this.dataFormatService.DataFormatInfoUpdated += OnDataFormatUpdated;
// Initialize and start
this.dataFormatService.Initialise();
this.dataFormatService.Start();
}
public void DefineDataFormats()
{
const string DataSource = "DataSourceX";
// Define first parameter group
var group1Params = dataFormatService.GetParameterDataFormatId(
DataSource,
new[] { "Param1", "Param2", "Param3", "Param4" });
if (group1Params.Success && group1Params.Data != null)
{
Console.WriteLine($"Group 1 parameters format ID: {group1Params.Data.DataFormatId}");
}
// Define second parameter group
var group2Params = dataFormatService.GetParameterDataFormatId(
DataSource,
new[] { "Param5", "Param6", "Param7" });
if (group2Params.Success && group2Params.Data != null)
{
Console.WriteLine($"Group 2 parameters format ID: {group2Params.Data.DataFormatId}");
}
// Define individual parameter (single parameter is still a list)
var singleParam = dataFormatService.GetParameterDataFormatId(
DataSource,
new[] { "Param8" });
// Define events
var event1 = dataFormatService.GetEventDataFormatId(DataSource, "EventA");
var event2 = dataFormatService.GetEventDataFormatId(DataSource, "EventB");
var event3 = dataFormatService.GetEventDataFormatId(DataSource, "EventC");
// Retrieve all formats
var allFormats = dataFormatService.GetDataSourceDataFormatInfo(DataSource);
if (allFormats.Success && allFormats.Data != null)
{
Console.WriteLine($"\nTotal formats defined: {allFormats.Data.Count}");
var paramFormats = allFormats.Data.Where(f => f.DataFormatInfoType == DataFormatInfoType.Parameters);
var eventFormats = allFormats.Data.Where(f => f.DataFormatInfoType == DataFormatInfoType.Event);
Console.WriteLine($"Parameter formats: {paramFormats.Count()}");
Console.WriteLine($"Event formats: {eventFormats.Count()}");
}
}
public void LookupFormats()
{
const string DataSource = "DataSourceX";
// Create a format
var createResult = dataFormatService.GetParameterDataFormatId(
DataSource,
new[] { "Param1", "Param2" });
if (!createResult.Success || createResult.Data == null)
{
return;
}
var formatId = createResult.Data.DataFormatId;
// Later, look up what parameters this format contains
var lookupResult = dataFormatService.GetParametersList(DataSource, formatId);
if (lookupResult.Success && lookupResult.Data != null)
{
Console.WriteLine($"Format {formatId} contains:");
foreach (var param in lookupResult.Data.ParameterList)
{
Console.WriteLine($" - {param}");
}
}
}
private void OnDataFormatUpdated(object sender, DataFormatInfo formatInfo)
{
Console.WriteLine($"[Event] Data formats updated: {string.Join(",",formatInfo.DataFormats)}");
Console.WriteLine($" Type: {formatInfo.DataFormatInfoType}");
Console.WriteLine($" Identifiers: {string.Join(", ", formatInfo.Identifiers)}");
}
}
```
## Best Practices
1. **Define Formats Early**: Define all data formats at the beginning of your session before streaming data.
2. **Group Related Parameters**: Group parameters that are logically related and will be sent together in packets.
3. **Consistent Naming**: Use consistent parameter and event naming conventions across your application.
4. **Cache Format IDs**: Store format IDs after creation to avoid repeated lookups.
5. **Check Return Values**: Always validate the `ApiResult` success and data before using format IDs.
6. **Per-Source Isolation**: Remember that formats are isolated per data source - the same parameter names in different data sources will have different format IDs.
## Data Source Organization
```csharp
public class MultiSourceFormats
{
private readonly IDataFormatManagementService formatService;
public void DefineFormatsForMultipleSources()
{
var sources = new[] { "DataSourceA", "DataSourceB", "DataSourceC" };
var parameters = new[] { "Param1", "Param2", "Param3" };
foreach (var source in sources)
{
// Each source gets its own format space
var result = formatService.GetParameterDataFormatId(source, parameters);
if (result.Success && result.Data != null)
{
Console.WriteLine($"{source} format ID: {result.Data.DataFormatId}");
// Different IDs for each source even with same parameters
}
}
}
}
```
## Error Handling
```csharp
var result = dataFormatService.GetParameterDataFormatId(dataSource, parameterList);
if (!result.Success)
{
Console.WriteLine($"Error creating parameter format: {result.Message}");
// Handle the error
return;
}
if (result.Data == null)
{
Console.WriteLine("Error: No data returned despite success");
return;
}
// Use the format ID
var formatId = result.Data.DataFormatId;
```
## Integration with Other Modules
### With Writer Module
```csharp
// Define the format
var formatResult = dataFormatService.GetParameterDataFormatId(
dataSource,
new[] { "Speed", "RPM" });
// Use the format ID when writing packets
if (formatResult.Success && formatResult.Data != null)
{
var formatId = formatResult.Data.DataFormatId;
// Create packet with this format ID and write using Writer Module
}
```
### With Session Manager
```csharp
// Create a session
var sessionResult = sessionService.CreateNewSession(
new SessionCreationDto(dataSource: "CarA"));
// Define formats for this session's data
var formatResult = dataFormatService.GetParameterDataFormatId(
"CarA",
new[] { "Speed", "RPM", "Throttle" });
```
## See Also
- [Session Manager Module](session-manager.md)
- [Writer Module](writer-module.md)
- [Reader Module](reader-module.md)
- [API Reference](api-reference.md)
---
# Writer Module
## Overview
The Writer Module (Packet Writing Module) provides API for publishing data packets and session information to the streaming broker (Kafka). It handles the serialization and transmission of telemetry data, events, markers, and session metadata.
## Key Features
- **Packet Writing**: Publish data packets to specific streams
- **Session Info Publishing**: Write session-related information to the broker
- **Multiple Stream Support**: Write to different streams within a session
- **Info Type Support**: Publish different types of information (SessionInfo, DataFormatInfo, etc.)
- **Automatic Serialization**: Handles packet serialization internally
- **Error Handling**: Returns detailed results for each write operation
## API Access
### Get the Writer API
```csharp
var writerApi = supportLibApi.GetWritingPacketApi();
```
### Create a Writer Service
```csharp
var serviceResult = writerApi.CreateService();
if (serviceResult.Success && serviceResult.Data != null)
{
var writerService = serviceResult.Data;
// Initialize and start the service
writerService.Initialise();
writerService.Start();
}
```
**Note**: Unlike Reader services, Writer services are not tied to a specific session. A single writer service can write to multiple sessions and data sources.
## Methods
### WriteData
Writes a data packet to a specific stream within a session.
```csharp
public ApiResult WriteData(
string dataSource,
string stream,
string sessionKey,
Packet packet)
```
**Parameters:**
- `dataSource`: The data source identifier
- `stream`: The stream name within the session
- `sessionKey`: The session key to write to
- `packet`: The packet to write
**Returns:**
- `ApiResult` indicating success or failure
**Example:**
```csharp
using MA.Streaming.OpenData;
// Create a packet (example with PeriodicDataPacket)
var periodicPacket = new PeriodicDataPacket
{
DataFormat = new SampleDataFormat
{
DataFormatIdentifier = 1234
},
StartTime = 123456,
Interval = 1000000, // 1ms in nanoseconds
Columns =
{
new SampleColumn[]
{
new()
{
DoubleSamples = new DoubleSampleList
{
Samples =
{
new DoubleSample[]
{
new DoubleSample
{
Status = DataStatus.Valid,
Value = 123456
}
}
}
}
}
}
}
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = periodicPacket.ToByteString(),
Id = packetCounter++,
Type = "PeriodicData",
IsEssential = false
};
var result = writerService.WriteData(
dataSource: "CarA",
stream: "Telemetry",
sessionKey: sessionKey,
packet: packet);
if (result.Success)
{
Console.WriteLine("Packet written successfully");
}
else
{
Console.WriteLine($"Failed to write packet: {result.Message}");
}
```
### WriteInfo
Writes information packets (metadata) to the broker.
```csharp
public ApiResult WriteInfo(
Packet packet,
InfoType infoType = InfoType.SessionInfo)
```
**Parameters:**
- `packet`: The information packet to write
- `infoType`: The type of information (default: SessionInfo)
**InfoType Values:**
- `InfoType.SessionInfo`: Session-related information
- `InfoType.DataFormatInfo`: Data format definitions
- `InfoType.Other`: Other metadata types
**Example:**
```csharp
var infoPacket = new Packet
{
SessionKey = sessionKey,
Content = sessionInfoData.ToByteString(),
Type = "SessionInfo",
IsEssential = true
};
var result = writerService.WriteInfo(
packet: infoPacket,
infoType: InfoType.SessionInfo);
if (!result.Success)
{
Console.WriteLine($"Failed to write info: {result.Message}");
}
```
## Packet Types
The library supports various packet types from the MA.Streaming.OpenData namespace:
### Data Packets
- **PeriodicDataPacket**: Regular interval data (e.g., 100Hz telemetry)
- **RowDataPacket**: Timestamped data rows
- **SynchroDataPacket**: Data logged in synchronous of another.
- **EventPacket**: Event occurrences
- **MarkerPacket**: Session markers
- **ErrorPacket**: Error occurrences.
- **RawCANPacket**: Raw CAN packets.
- **ConfigurationPacket**: Packet containing list of parameters, events, and group definitions. This packet must be sent after creating the session and before writing data, so that consumers (e.g. ATLAS) know how to interpret the parameters.
### Control Packets
- **NewSessionPacket**: Session start indicator
- **EndOfSessionPacket**: Session end indicator
- **DataFormatDefinitionPacket**: Format definitions
- **CoverageCursorInfoPacket**: Data coverage information
## Complete Example
```csharp
using Google.Protobuf;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Abstractions;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.DataFormatInfoModule;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.SessionInfoModule;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.SessionInfoModule.Abstractions;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.WritingModule;
using MA.Streaming.OpenData;
public class DataPublisher
{
private readonly IPacketWriterService writerService;
private readonly ISessionManagementService sessionService;
private readonly IDataFormatManagementService formatService;
private readonly string dataSource;
private ulong packetId;
public DataPublisher(
ISupportLibApi supportLibApi,
string dataSource)
{
this.dataSource = dataSource;
// Get writer service
var writerApi = supportLibApi.GetWritingPacketApi();
this.writerService = writerApi.CreateService().Data;
this.writerService.Initialise();
this.writerService.Start();
// Get session and format services
var sessionApi = supportLibApi.GetSessionManagerApi();
this.sessionService = sessionApi.CreateService().Data;
this.sessionService.Initialise();
this.sessionService.Start();
var formatApi = supportLibApi.GetDataFormatManagerApi();
this.formatService = formatApi.CreateService().Data;
this.formatService.Initialise();
this.formatService.Start();
}
public void PublishSession()
{
// 1. Create session
var sessionResult = this.sessionService.CreateNewSession(
new SessionCreationDto(
dataSource: this.dataSource,
identifier: "TestRun_001",
type: "Testing",
details:
[
new SessionDetailDto("Driver", "TestDriver"), new SessionDetailDto("Track", "TestTrack")
]));
if (!sessionResult.Success ||
sessionResult.Data == null)
{
Console.WriteLine($"Failed to create session: {sessionResult.Message}");
return;
}
var sessionKey = sessionResult.Data.SessionKey;
Console.WriteLine($"Created session: {sessionKey}");
// 2. Define data formats
var engineFormatResult = this.formatService.GetParameterDataFormatId(
this.dataSource,
[
"RPM", "EngineTemp", "Throttle"
]);
if (!engineFormatResult.Success ||
engineFormatResult.Data == null)
{
Console.WriteLine("Failed to create format");
return;
}
var engineFormatId = engineFormatResult.Data.DataFormatId;
// 3. Send session start packet
this.SendSessionStartPacket(sessionKey);
// 4. Send periodic data
for (int i = 0; i < 100; i++)
{
this.SendPeriodicData(sessionKey, engineFormatId, (ulong)i * 10000); // 10ms intervals
Thread.Sleep(10); // Simulate real-time
}
// 5. Send session end packet
this.SendSessionEndPacket(sessionKey);
// 6. Mark session as complete
this.sessionService.EndSession(this.dataSource, sessionKey);
Console.WriteLine("Session publishing complete");
}
private void SendSessionStartPacket(string sessionKey)
{
var startPacket = new NewSessionPacket
{
DataSource = this.dataSource,
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = startPacket.ToByteString(),
Id = this.packetId++,
Type = nameof(NewSessionPacket).Replace("Packet", ""),
IsEssential = true
};
this.writerService.WriteData(this.dataSource, "Main", sessionKey, packet);
}
private void SendPeriodicData(string sessionKey, ulong formatId, ulong timestamp)
{
var periodicData = new PeriodicDataPacket
{
DataFormat = new SampleDataFormat
{
DataFormatIdentifier = formatId
},
StartTime = timestamp,
Interval = 10000000, // 10ms in nanoseconds
// Add sample values (RPM, EngineTemp, Throttle)
Columns =
{
new SampleColumn[]
{
new()
{
DoubleSamples = new DoubleSampleList
{
Samples =
{
new DoubleSample[]
{
new()
{
Value = 8500.0,
Status = DataStatus.Valid
},
new()
{
Value = 8501.0,
Status = DataStatus.Valid
},
new()
{
Value = 8502.0,
Status = DataStatus.Valid
}
}
}
}
},
new()
{
DoubleSamples = new DoubleSampleList
{
Samples =
{
new DoubleSample[]
{
new()
{
Value = 92.5,
Status = DataStatus.Valid
},
new()
{
Value = 92.5,
Status = DataStatus.Valid
},
new()
{
Value = 92.6,
Status = DataStatus.Valid
}
}
}
}
},
new()
{
DoubleSamples = new DoubleSampleList
{
Samples =
{
new DoubleSample[]
{
new()
{
Value = 0.85,
Status = DataStatus.Valid
},
new()
{
Value = 0.86,
Status = DataStatus.Valid
},
new()
{
Value = 0.87,
Status = DataStatus.Valid
}
}
}
}
}
}
}
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = periodicData.ToByteString(),
Id = this.packetId++,
Type = nameof(PeriodicDataPacket).Replace("Packet", ""),
IsEssential = false
};
var result = this.writerService.WriteData(this.dataSource, "Telemetry", sessionKey, packet);
if (!result.Success)
{
Console.WriteLine($"Failed to write data: {result.Message}");
}
}
private void SendSessionEndPacket(string sessionKey)
{
var endPacket = new EndOfSessionPacket
{
DataSource = this.dataSource
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = endPacket.ToByteString(),
Id = this.packetId++,
Type = nameof(EndOfSessionPacket).Replace("Packet", ""),
IsEssential = true
};
this.writerService.WriteData(this.dataSource, "Main", sessionKey, packet);
}
}
```
## Writing Different Packet Types
### Periodic Data (Regular Intervals)
```csharp
public void WritePeriodicData(string sessionKey, ulong formatId, ulong timestamp)
{
var periodicData = new PeriodicDataPacket
{
DataFormat = new SampleDataFormat
{
DataFormatIdentifier = formatId
},
StartTime = timestamp,
Interval = 1000000, // 1ms in nanoseconds
Columns =
[
new SampleColumn
{
DoubleSamples = new DoubleSampleList
{
Samples = [
new DoubleSample
{
Value = 100.5,
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 101.2,
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 102.0,
Status = DataStatus.Valid
}
]
}
}
]
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = periodicData.ToByteString(),
Id = packetId++,
Type = "PeriodicData",
IsEssential = false
};
writerService.WriteData(dataSource, "Telemetry", sessionKey, packet);
}
```
### Row Data (Timestamped Rows)
```csharp
public void WriteRowData(string sessionKey, ulong formatId)
{
var rowData = new RowDataPacket
{
DataFormat = new SampleDataFormat
{
DataFormatIdentifier = formatId
},
// The number of rows and timestamps must match.
Timestamps = [ 1000000, 1001000, 1002000 ],
Rows =
[
new SampleRow
{
DoubleSamples = new DoubleSampleList
{
Samples =
[
// Add values for each parameter
new DoubleSample
{
Value = 100.0
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 101.0
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 102.0
Status = DataStatus.Valid
},
]
}
},
new SampleRow
{
DoubleSamples = new DoubleSampleList
{
Samples =
[
// Add values for each parameter
new DoubleSample
{
Value = 101.0
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 102.0
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 103.0
Status = DataStatus.Valid
},
]
}
},
new SampleRow
{
DoubleSamples = new DoubleSampleList
{
Samples =
[
// Add values for each parameter
new DoubleSample
{
Value = 102.0
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 103.0
Status = DataStatus.Valid
},
new DoubleSample
{
Value = 104.0
Status = DataStatus.Valid
},
]
}
}
]
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = rowData.ToByteString(),
Id = packetId++,
Type = "RowData",
IsEssential = false
};
writerService.WriteData(dataSource, "VariableRate", sessionKey, packet);
}
```
### Event Data
```csharp
public void WriteEvent(string sessionKey, ulong eventFormatId, ulong timestamp)
{
var eventData = new EventPacket
{
DataFormat = new EventDataFormat
{
DataFormatIdentifier = eventFormatId
},
Timestamp = timestamp
RawValues = [/* add raw values for the event if needed */]
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = eventData.ToByteString(),
Id = packetId++,
Type = "EventData",
IsEssential = true
};
writerService.WriteData(dataSource, "Events", sessionKey, packet);
}
```
### Marker Data
```csharp
public void WriteMarker(string sessionKey, string markerLabel, ulong timestamp)
{
var markerData = new MarkerPacket
{
Timestamp = timestamp,
Label = markerLabel,
Description = "Important event marker"
};
var packet = new Packet
{
SessionKey = sessionKey,
Content = markerData.ToByteString(),
Id = packetId++,
Type = "MarkerData",
IsEssential = false
};
writerService.WriteData(dataSource, "Markers", sessionKey, packet);
}
```
## Best Practices
1. **Initialize Once**: Create a single writer service that can write to multiple sessions.
2. **Sequential Packet IDs**: Maintain a counter for packet IDs to ensure proper ordering.
3. **Mark Essential Packets**: Set `IsEssential = true` for critical packets (session start/end, format definitions).
4. **Use Appropriate Streams**: Organize data into logical streams (e.g., "Telemetry", "Events", "Markers").
5. **Send Session Lifecycle Packets**: Always send NewSessionPacket at start and EndOfSessionPacket at end of each stream.
6. **Send ConfigurationPacket Early**: After creating and starting the session, send a `ConfigurationPacket` with your parameter definitions before writing data. This tells consumers how to interpret the data.
7. **Define Formats Before Data**: Create data formats (to get format IDs) before sending data packets that reference them.
8. **Handle Write Failures**: Always check the result and handle failures appropriately.
9. **Batch When Possible**: Group related data in single packets to reduce overhead.
## Error Handling
```csharp
public bool SafeWriteData(string dataSource, string stream, string sessionKey, Packet packet)
{
var result = writerService.WriteData(dataSource, stream, sessionKey, packet);
if (!result.Success)
{
logger.Error($"Failed to write packet {packet.Id}: {result.Message}");
// Implement retry logic if needed
for (int retry = 0; retry < 3; retry++)
{
Thread.Sleep(100 * (retry + 1));
result = writerService.WriteData(dataSource, stream, sessionKey, packet);
if (result.Success)
{
logger.Info($"Packet {packet.Id} written on retry {retry + 1}");
return true;
}
}
return false;
}
return true;
}
```
## Integration with Other Modules
### With Session Manager
```csharp
// Create session first
var sessionResult = sessionService.CreateNewSession(sessionDto);
var sessionKey = sessionResult.Data.SessionKey;
// Then write data to that session
writerService.WriteData(dataSource, stream, sessionKey, packet);
// End session when done
sessionService.EndSession(dataSource, sessionKey);
```
### With Data Format Manager
```csharp
// Define format first
var formatResult = formatService.GetParameterDataFormatId(dataSource, parameters);
var formatId = formatResult.Data.DataFormatId;
// Create packet with format ID
var periodicData = new PeriodicDataPacket
{
DataFormat = new SampleDataFormat{DataFormatIdentifier = formatId},
// ... data
};
// Write the packet
writerService.WriteData(dataSource, stream, sessionKey, packet);
```
## Performance Considerations
1. **Minimize Serialization Overhead**: Reuse packet objects when possible
2. **Batch Data**: Combine multiple values in single packets
3. **Use Appropriate Intervals**: Don't send data more frequently than needed
4. **Stream Selection**: Use different streams to parallelize writes
5. **Essential Flag**: Use sparingly to avoid unnecessary broker overhead
## Cleanup
```csharp
// When done with the writer service
writerService.Stop();
```
## See Also
- [Session Manager Module](session-manager.md)
- [Data Format Manager Module](data-format-manager.md)
- [Reader Module](reader-module.md)
- [API Reference](api-reference.md)
---
# Reader Module
## Overview
The Reader Module (Packet Reading Module) provides API for consuming data packets from the streaming broker. It supports both live session monitoring and historical session playback, with configurable options for stream filtering, auto-start behavior, and inactivity timeout.
## Key Features
- **Live Reading**: Monitor live sessions as data arrives
- **Historical Playback**: Read complete historical sessions
- **Stream Filtering**: Read specific streams or all streams
- **Auto-Start or Manual Start**: Control when reading begins
- **Coverage Cursor Support**: Track data availability and gaps
- **Event System**: Rich events for tracking reading progress
- **Handler Pattern**: Attach custom handlers to process packets
- **Session Pattern Matching**: Read sessions matching specific patterns
- **Inactivity Timeout**: Automatically stop reading after inactivity period
## API Access
### Get the Reader API
```csharp
var readerApi = supportLibApi.GetReadingPacketApi();
```
### Create a Reader Service
There are two ways to create a reader service:
#### Option 1: Simple Creation (Data Source + Session Key)
```csharp
var serviceResult = readerApi.CreateService(
dataSource: "CarA",
sessionKey: "specific-session-key");
if (serviceResult.Success && serviceResult.Data != null)
{
var readerService = serviceResult.Data;
}
```
#### Option 2: Advanced Creation (Using Configuration)
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.ReadingModule;
var config = new PacketReadingConfiguration(
dataSource: "CarA",
sessionIdentifierPattern: "*", // Match all sessions
readingType: ReadingType.Live,
streams: new[] { "Telemetry", "Events" },
excludeMainStream: false,
inactivityTimeoutSeconds: 30,
sessionKey: null,
liveReadingType: LiveReadingType.FromBeginning,
bufferLength: 1000,
groupId: "my-consumer-group");
var serviceResult = readerApi.CreateService(config);
```
## Configuration Options
### PacketReadingConfiguration
```csharp
public PacketReadingConfiguration(
string? dataSource = "Default",
string? sessionIdentifierPattern = "*",
ReadingType? readingType = ReadingType.Live,
IReadOnlyList? streams = null,
bool? excludeMainStream = false,
uint? inactivityTimeoutSeconds = 30,
string? sessionKey = null,
LiveReadingType? liveReadingType = null,
int? bufferLength = null,
string? groupId = null,
IReadOnlyList? excludedStreams = null)
```
**Parameters:**
- **dataSource**: The data source to read from (default: "Default")
- **sessionIdentifierPattern**: Pattern for matching session identifiers
- Use `"*"` to match all session identifires
- Use specific identifier to match exact session
- **readingType**: Type of reading mode
- `ReadingType.Live`: Monitor live sessions
- `ReadingType.Historical`: Read completed sessions
- **streams**: List of specific streams to read (default: all streams)
- `null` or empty list reads all streams
- Specify streams like `["Telemetry", "Events"]` to filter
- **excludeMainStream**: Whether to exclude the main stream (default: false)
- **inactivityTimeoutSeconds**: Timeout in seconds after which reading stops if no data arrives (default: 30)
- **sessionKey**: Specific session key to read (optional)
- If provided, only this session is read
- If null, pattern matching is used
- **liveReadingType**: Type of live reading mode (default: `LiveReadingType.FromBeginning`)
- `LiveReadingType.FromBeginning`: Read from the start of the session
- `LiveReadingType.LeadingEdge`: Read only new data from the current point forward (skip historical data)
- **bufferLength**: Size of the internal buffer for packets (default: 0 = use system default)
- Larger buffers can handle higher data rates but use more memory
- Set to appropriate size based on expected packet rate and processing speed
- Value of 0 uses the default unbounded buffer
- **groupId**: Kafka consumer group identifier (default: empty string = auto-generated)
- Use a specific group ID to control consumer group membership
- Multiple readers with same group ID share the load (Kafka consumer group behavior)
- Use different group IDs for independent readers of the same topic
- Empty string creates a unique consumer group per reader
- **excludedStreams**: List of streams to skip when reading a session (default: empty = nothing excluded)
- Applied after the `streams` selection: a stream that appears in both lists is not read
- Useful to read everything except a few known-noisy streams, without having to list every stream you do want in `streams`
### ReadingType Enum
```csharp
public enum ReadingType
{
Live, // Read live sessions
Historical // Read historical (completed) sessions
}
```
### LiveReadingType Enum
```csharp
public enum LiveReadingType
{
FromBeginning = 0, // Read live session from the beginning
LeadingEdge = 1 // Read live session from the current point (skip past data)
}
```
**LiveReadingType Details:**
- **FromBeginning** (default): When reading a live session, start from the beginning and process all available data, then continue with live data as it arrives. This ensures you get the complete session history.
- **LeadingEdge**: When reading a live session, skip any historical data and start reading from the current point forward. This is useful for real-time monitoring where you only care about the latest data and want to minimize latency. Also known as "tail mode" or "live-only mode".
**Use Cases:**
- Use `FromBeginning` when you need the complete session data (e.g., analysis, visualization)
- Use `LeadingEdge` when you only need real-time updates (e.g., live dashboards, alerts)
**Note**: `LiveReadingType` only applies when `ReadingType` is set to `Live`. It has no effect for historical session reading.
## Methods
### AddHandler
Adds a packet handler to process received packets.
```csharp
public void AddHandler(IHandler handler)
```
**Example:**
```csharp
public class MyPacketHandler : IHandler
{
public void Handle(IReceivedPacketDto receivedPacket)
{
var packet = receivedPacket.Packet;
Console.WriteLine($"Received: {packet.Type} (ID: {packet.Id})");
// Process based on packet type
switch (packet.Type)
{
case "PeriodicData":
HandlePeriodicData(packet);
break;
case "Event":
HandleEvent(packet);
break;
}
}
private void HandlePeriodicData(Packet packet)
{
var periodicData = PeriodicDataPacket.Parser.ParseFrom(packet.Content);
// Process periodic data...
}
private void HandleEvent(Packet packet)
{
var eventData = EventPacket.Parser.ParseFrom(packet.Content);
// Process event...
}
}
// Usage
var handler = new MyPacketHandler();
readerService.AddHandler(handler);
```
### RemoveHandler
Removes a previously added handler.
```csharp
public void RemoveHandler(IHandler handler)
```
**Example:**
```csharp
readerService.RemoveHandler(handler);
```
### Initialise and Start
Initialize and start the reader service.
```csharp
readerService.Initialise();
readerService.Start();
```
**Note**:
- `Initialise()` prepares the service
- `Start()` begins reading packets
- For auto-start readers, packets begin arriving immediately after `Start()`
- For manual-start readers, `Start()` waits for the session to begin
### Stop
Stops the reader service.
```csharp
readerService.Stop();
```
## Events
### SessionReadingStarted
Fired when reading of a session begins.
```csharp
readerService.SessionReadingStarted += (sender, sessionInfo) =>
{
Console.WriteLine($"Started reading session: {sessionInfo.SessionKey}");
Console.WriteLine($"Data Source: {sessionInfo.DataSource}");
Console.WriteLine($"Session Type: {sessionInfo.Type}");
};
```
### SessionReadingCompleted
Fired when reading of a session is complete.
```csharp
readerService.SessionReadingCompleted += (sender, sessionInfo) =>
{
Console.WriteLine($"Completed reading session: {sessionInfo.SessionKey}");
Console.WriteLine($"Historical: {sessionInfo.Historical}");
};
```
### StreamReadingStarted
Fired when reading of a stream begins.
```csharp
readerService.StreamReadingStarted += (sender, streamInfo) =>
{
Console.WriteLine($"Started reading stream: {streamInfo.Stream}");
Console.WriteLine($"Session: {streamInfo.SessionKey}");
};
```
### StreamReadingCompleted
Fired when reading of a stream is complete.
```csharp
readerService.StreamReadingCompleted += (sender, streamInfo) =>
{
Console.WriteLine($"Completed reading stream: {streamInfo.Stream}");
};
```
### SessionInfoUpdated
Fired when session information changes during reading.
```csharp
readerService.SessionInfoUpdated += (sender, sessionInfo) =>
{
Console.WriteLine($"Session info updated: {sessionInfo.SessionKey}");
Console.WriteLine($"Details: {sessionInfo.Details.Count}");
};
```
### SessionAssociationInfoUpdated
Fired when session association information is detected.
```csharp
readerService.SessionAssociationInfoUpdated += (sender, associationInfo) =>
{
Console.WriteLine($"Association detected:");
Console.WriteLine($" Main: {associationInfo.MainSessionInfo.SessionKey}");
Console.WriteLine($" Associate: {associationInfo.AssociateSessionInfo.SessionKey}");
};
```
### CoverageCursorReceived
Fired when a coverage cursor packet is received.
```csharp
readerService.CoverageCursorReceived += (sender, coverageCursor) =>
{
Console.WriteLine($"Coverage cursor received:");
Console.WriteLine($" Data Source: {coverageCursor.DataSource}");
Console.WriteLine($" Time: {coverageCursor.CoverageCursorTime}");
};
```
**Coverage Cursor**: Indicates the latest timestamp where all of the data has been received. Useful for post processing data in real time.
## Complete Examples
### Example 1: Read Historical Session
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.ReadingModule.Abstractions;
using MA.Streaming.OpenData;
public class HistoricalSessionReader
{
private readonly IPacketReaderService readerService;
private readonly AutoResetEvent completionEvent = new(false);
private int packetCount = 0;
public HistoricalSessionReader(ISupportLibApi supportLibApi, string dataSource, string sessionKey)
{
var readerApi = supportLibApi.GetReadingPacketApi();
// Create reader for specific session
var result = readerApi.CreateService(dataSource, sessionKey);
this.readerService = result.Data;
// Subscribe to events
this.readerService.SessionReadingStarted += OnReadingStarted;
this.readerService.SessionReadingCompleted += OnReadingCompleted;
// Add packet handler
this.readerService.AddHandler(new PacketCounter(this));
// Initialize
this.readerService.Initialise();
}
public void ReadSession()
{
Console.WriteLine("Starting to read historical session...");
readerService.Start();
// Wait for completion
completionEvent.WaitOne(TimeSpan.FromMinutes(5));
Console.WriteLine($"Total packets read: {packetCount}");
}
private void OnReadingStarted(object sender, ISessionInfo session)
{
Console.WriteLine($"Reading started: {session.Identifier}");
}
private void OnReadingCompleted(object sender, ISessionInfo session)
{
Console.WriteLine($"Reading completed: {session.Identifier}");
completionEvent.Set();
}
private class PacketCounter : IHandler
{
private readonly HistoricalSessionReader parent;
public PacketCounter(HistoricalSessionReader parent)
{
this.parent = parent;
}
public void Handle(IReceivedPacketDto receivedPacket)
{
parent.packetCount++;
if (parent.packetCount % 1000 == 0)
{
Console.WriteLine($"Processed {parent.packetCount} packets...");
}
}
}
}
```
### Example 2: Monitor Live Session
```csharp
public class LiveSessionMonitor
{
private readonly IPacketReaderService readerService;
public LiveSessionMonitor(
ISupportLibApi supportLibApi,
ISessionManagementService sessionService,
string dataSource)
{
// Subscribe to session started event
sessionService.LiveSessionStarted += (sender, session) =>
{
if (session.DataSource == dataSource)
{
StartReadingLiveSession(supportLibApi, session);
}
};
}
private void StartReadingLiveSession(ISupportLibApi supportLibApi, ISessionInfo session)
{
Console.WriteLine($"New live session detected: {session.SessionKey}");
var readerApi = supportLibApi.GetReadingPacketApi();
// Create reader for the live session
var config = new PacketReadingConfiguration(
dataSource: session.DataSource,
sessionKey: session.SessionKey,
readingType: ReadingType.Live,
streams: new[] { "Telemetry", "Events" }, // Only read specific streams
inactivityTimeoutSeconds: 60);
var result = readerApi.CreateService(config);
var readerService = result.Data;
// Add handlers
readerService.AddHandler(new LiveDataHandler());
// Subscribe to events
readerService.SessionReadingCompleted += (sender, sessionInfo) =>
{
Console.WriteLine($"Live session ended: {sessionInfo.SessionKey}");
readerService.Stop();
};
// Start reading
readerService.Initialise();
readerService.Start();
}
private class LiveDataHandler : IHandler
{
public void Handle(IReceivedPacketDto packet)
{
// Process live data in real-time
Console.WriteLine($"[{DateTime.UtcNow:HH:mm:ss.fff}] {packet.Packet.Type}");
}
}
}
```
### Example 3: Read All Sessions with Pattern
```csharp
public class SessionPatternReader
{
public void ReadAllQualifyingSessions(ISupportLibApi supportLibApi)
{
var readerApi = supportLibApi.GetReadingPacketApi();
// Read all historical qualifying sessions
var config = new PacketReadingConfiguration(
dataSource: "RaceCar",
sessionIdentifierPattern: "Qualifying_*", // Pattern matching
readingType: ReadingType.Both,
inactivityTimeoutSeconds: 30);
var result = readerApi.CreateService(config);
var readerService = result.Data;
var sessionPackets = new Dictionary>();
// Track packets by session
readerService.SessionReadingStarted += (sender, session) =>
{
sessionPackets[session.SessionKey] = new List();
Console.WriteLine($"Reading session: {session.Identifier}");
};
// Collect packets
readerService.AddHandler(new SessionPacketCollector(sessionPackets));
readerService.SessionReadingCompleted += (sender, session) =>
{
var count = sessionPackets[session.SessionKey].Count;
Console.WriteLine($"Session {session.Identifier} had {count} packets");
};
readerService.Initialise();
readerService.Start();
// Wait for completion...
}
private class SessionPacketCollector : IHandler
{
private readonly Dictionary> packets;
public SessionPacketCollector(Dictionary> packets)
{
this.packets = packets;
}
public void Handle(IReceivedPacketDto packet)
{
var sessionKey = packet.Packet.SessionKey;
if (packets.ContainsKey(sessionKey))
{
packets[sessionKey].Add(packet);
}
}
}
}
```
### Example 4: Leading Edge Live Reading
```csharp
public class RealTimeDashboard
{
public void MonitorLiveSession(ISupportLibApi supportLibApi, string dataSource, string sessionKey)
{
var readerApi = supportLibApi.GetReadingPacketApi();
// Configure for leading edge reading - only new data
var config = new PacketReadingConfiguration(
dataSource: dataSource,
sessionKey: sessionKey,
readingType: ReadingType.Live,
liveReadingType: LiveReadingType.LeadingEdge, // Skip historical data
inactivityTimeoutSeconds: 60);
var result = readerApi.CreateService(config);
var readerService = result.Data;
readerService.SessionReadingStarted += (sender, session) =>
{
Console.WriteLine($"Started monitoring live session from current point");
};
// Process only new live data
readerService.AddHandler(new RealtimeDataHandler());
readerService.Initialise();
readerService.Start();
}
private class RealtimeDataHandler : IHandler
{
private DateTime lastUpdate = DateTime.UtcNow;
public void Handle(IReceivedPacketDto packet)
{
var latency = DateTime.UtcNow - packet.SubmitTime;
Console.WriteLine($"[{DateTime.UtcNow:HH:mm:ss.fff}] Packet: {packet.Packet.Type}, Latency: {latency.TotalMilliseconds}ms");
lastUpdate = DateTime.UtcNow;
}
}
}
```
### Example 5: Bounded Buffer for High-Volume Sessions
```csharp
public class HighVolumeSessionReader
{
public void ReadHighVolumeSession(ISupportLibApi supportLibApi, string dataSource, string sessionKey)
{
var readerApi = supportLibApi.GetReadingPacketApi();
// Configure with bounded buffer to control memory usage
var config = new PacketReadingConfiguration(
dataSource: dataSource,
sessionKey: sessionKey,
readingType: ReadingType.Historical,
bufferLength: 10000, // Limit buffer to 10,000 packets
inactivityTimeoutSeconds: 30);
var result = readerApi.CreateService(config);
var readerService = result.Data;
Console.WriteLine("Reading high-volume session with bounded buffer...");
readerService.AddHandler(new BatchProcessor());
readerService.Initialise();
readerService.Start();
}
private class BatchProcessor : IHandler
{
private readonly List batch = new();
private const int BatchSize = 1000;
public void Handle(IReceivedPacketDto packet)
{
batch.Add(packet);
if (batch.Count >= BatchSize)
{
ProcessBatch(batch);
batch.Clear();
}
}
private void ProcessBatch(List packets)
{
Console.WriteLine($"Processing batch of {packets.Count} packets");
// Batch processing logic here
}
}
}
```
### Example 6: Using Consumer Groups
```csharp
public class DistributedProcessing
{
public void SetupDistributedReaders(ISupportLibApi supportLibApi, string dataSource, string sessionKey)
{
// Create multiple readers in the same consumer group for load balancing
var groupId = "processing-cluster-1";
var readers = new List();
for (int i = 0; i < 3; i++)
{
var config = new PacketReadingConfiguration(
dataSource: dataSource,
sessionKey: sessionKey,
readingType: ReadingType.Historical,
groupId: groupId, // Same group ID for load balancing
inactivityTimeoutSeconds: 30);
var readerApi = supportLibApi.GetReadingPacketApi();
var result = readerApi.CreateService(config);
var reader = result.Data;
reader.AddHandler(new DistributedHandler(i));
reader.Initialise();
readers.Add(reader);
Console.WriteLine($"Reader {i} created in consumer group '{groupId}'");
}
// Start all readers - they will share the workload
foreach (var reader in readers)
{
reader.Start();
}
Console.WriteLine("Distributed processing started - readers sharing workload via consumer group");
}
private class DistributedHandler : IHandler
{
private readonly int readerId;
private int packetCount = 0;
public DistributedHandler(int readerId)
{
this.readerId = readerId;
}
public void Handle(IReceivedPacketDto packet)
{
packetCount++;
if (packetCount % 100 == 0)
{
Console.WriteLine($"Reader {readerId}: Processed {packetCount} packets");
}
}
}
}
```
### Example 7: Resuming from Last Position
```csharp
public class ResumableSessionReader
{
private const string CustomGroupId = "my-data-processor";
public void StartOrResumeSession(ISupportLibApi supportLibApi, string dataSource, string sessionKey)
{
var readerApi = supportLibApi.GetReadingPacketApi();
// Create a stable group ID combining custom group identifier and session key
// This allows resuming from the last committed position
var groupId = $"{CustomGroupId}_{sessionKey}";
var config = new PacketReadingConfiguration(
dataSource: dataSource,
sessionKey: sessionKey,
readingType: ReadingType.Live, // Use Live mode to enable resume behavior
liveReadingType = LiveReadingType.LeadingEdge,
groupId: groupId, // Consistent group ID for resumption
inactivityTimeoutSeconds: 60);
var result = readerApi.CreateService(config);
var readerService = result.Data;
Console.WriteLine($"Starting reader with group ID: {groupId}");
Console.WriteLine("If this is a restart, reading will resume from last committed position");
readerService.AddHandler(new CheckpointHandler());
readerService.SessionReadingStarted += (sender, session) =>
{
Console.WriteLine($"Session reading started/resumed: {session.SessionKey}");
};
readerService.Initialise();
readerService.Start();
// When this reader restarts with the same groupId, it will automatically
// resume from where it left off, thanks to Kafka consumer group offsets
}
private class CheckpointHandler : IHandler
{
private int processedCount = 0;
public void Handle(IReceivedPacketDto packet)
{
processedCount++;
// Process the packet
if (processedCount % 1000 == 0)
{
Console.WriteLine($"Processed {processedCount} packets (position automatically tracked by consumer group)");
}
}
}
}
```
## Best Practices
1. **Subscribe to Events First**: Attach event handlers before calling `Start()` to capture all events.
2. **Handle All Packet Types**: Implement handlers that can process different packet types gracefully.
3. **Use Configuration for Flexibility**: Use `PacketReadingConfiguration` for complex scenarios with multiple options.
4. **Stream Filtering**: Filter streams when you only need specific data to reduce processing overhead.
5. **Inactivity Timeout**: Set appropriate timeout values based on expected data frequency.
6. **Resource Cleanup**: Always call `Stop()` when done to release resources.
7. **Thread Safety**: Handlers may be called from different threads; ensure thread-safe processing.
8. **Error Handling in Handlers**: Wrap handler logic in try-catch to prevent crashes from processing errors.
9. **Choose Appropriate LiveReadingType**:
- Use `FromBeginning` for complete session analysis and when historical context is needed
- Use `LeadingEdge` for real-time dashboards and alerts where only current data matters
- `LeadingEdge` reduces latency and memory usage for live monitoring scenarios
10. **Buffer Size Configuration**:
- Use bounded buffers (`bufferLength > 0`) for high-volume sessions to prevent memory pressure
- Use unbounded buffers (default) for normal sessions where memory is not a concern
- Monitor memory usage and adjust buffer size based on packet rate and processing speed
- Ensure packet handlers are efficient to keep up with data flow; slow handlers with bounded buffers will cause backpressure
11. **Consumer Groups**:
- Use unique `groupId` for each independent processing pipeline
- Share `groupId` across readers only when you want load balancing/distributed processing
- Leave `groupId` empty (default) for single-reader scenarios
- Be aware that readers in the same group will split data - they won't all receive the same packets
- Group ID naming: avoid spaces and follow Kafka naming principles (use alphanumeric characters, hyphens, underscores, and periods)
- **Resuming from last position**: To rejoin a session and continue from where you left off, use `ReadingType.Live` with a consistent `groupId` pattern like `{customGroupId}_{sessionKey}`. This leverages Kafka consumer group offsets to resume from the last committed position.
- **Warning**: Do not reuse the same static `groupId` across different sessions. Using the same consumer group ID for multiple sessions can lead to reading from incorrect offsets, missing data, or late reading as Kafka will resume from the last committed position which may be from a different session. Always include the session key or unique identifier in your group ID to avoid these issues.
12. **Resumable Live Reading**:
- To implement fault-tolerant live reading that can resume after interruption, use `ReadingType.Live` with `LiveReadingType.LeadingEdge` and a session-specific `groupId` like `{customGroupId}_{sessionKey}`
- This pattern is ideal for applications that need to process all data even after crashes or restarts
- The reader will automatically resume from the last committed offset, avoiding data loss or duplicate processing
- Ensure your application logic is idempotent if there's a possibility of receiving duplicate messages during recovery
## Common Patterns
### Buffered Handler
```csharp
public class BufferedPacketHandler : IHandler
{
private readonly BlockingCollection buffer = new();
private readonly CancellationTokenSource cts = new();
public BufferedPacketHandler()
{
// Start processing thread
Task.Run(() => ProcessBuffer());
}
public void Handle(IReceivedPacketDto packet)
{
buffer.Add(packet);
}
private void ProcessBuffer()
{
foreach (var packet in buffer.GetConsumingEnumerable(cts.Token))
{
// Process packet asynchronously
ProcessPacket(packet);
}
}
private void ProcessPacket(IReceivedPacketDto packet)
{
// Your processing logic
}
public void Stop()
{
buffer.CompleteAdding();
cts.Cancel();
}
}
```
### Type-Specific Handlers
```csharp
public class TypeDispatchingHandler : IHandler
{
private readonly Dictionary> handlers = new();
public TypeDispatchingHandler()
{
handlers["PeriodicData"] = HandlePeriodicData;
handlers["Event"] = HandleEventData;
handlers["Marker"] = HandleMarkerData;
}
public void Handle(IReceivedPacketDto receivedPacket)
{
var packet = receivedPacket.Packet;
if (handlers.TryGetValue(packet.Type, out var handler))
{
handler(packet);
}
else
{
Console.WriteLine($"Unknown packet type: {packet.Type}");
}
}
private void HandlePeriodicData(Packet packet) { /* ... */ }
private void HandleEventData(Packet packet) { /* ... */ }
private void HandleMarkerData(Packet packet) { /* ... */ }
}
```
## See Also
- [Session Manager Module](session-manager.md)
- [Essentials Module](essentials-module.md) - Read essential/configuration packets only
- [Writer Module](writer-module.md)
- [Buffering Module](buffering-module.md)
- [API Reference](api-reference.md)
---
# Essential Module
## Overview
The Essentials Module provides a streamlined API for reading essential session packets from the streaming broker. Essential packets contain critical session information such as configuration data, data format definitions, and other metadata required to properly interpret session data. This module is optimized for efficiently retrieving these foundational packets without the overhead of processing all session data.
The lifecycle of the Essentials service is tied to the session lifecycle—it starts when the session begins and completes when all essential packets have been read or the session ends.
## Key Features
- **Essential Packet Reading**: Read only essential/configuration packets from sessions
- **Lightweight Processing**: Optimized for reading metadata without full data streams
- **Event System**: Track when essential data reading starts and completes
- **Handler Pattern**: Attach custom handlers to process essential packets
- **Live and Historical Support**: Works with both live and historical sessions
- **Stream Management**: Automatically manages connection to the Essential stream
## Use Cases
The Essentials Module is ideal for scenarios where you need to:
- Retrieve session configuration data before processing full telemetry
- Read session configuration and settings
- Access essential session metadata and setup information
- Validate session structure before initiating full data processing
- Build session indexes or catalogs
## API Access
### Get the Essentials API
```csharp
var essentialsApi = supportLibApi.GetEssentialsApi();
```
### Create an Essentials Service
```csharp
var serviceResult = essentialsApi.CreateService(
dataSource: "CarA",
sessionKey: "specific-session-key");
if (serviceResult.Success && serviceResult.Data != null)
{
var essentialsService = serviceResult.Data;
}
```
**Parameters:**
- **dataSource**: The data source to read from (e.g., "CarA", "CarB")
- **sessionKey**: The specific session key to read essential packets from
## Methods
### AddHandler
Adds a packet handler to process received essential packets.
```csharp
public void AddHandler(IHandler handler)
```
**Example:**
```csharp
public class EssentialPacketHandler : IHandler
{
public void Handle(IReceivedPacketDto receivedPacket)
{
var packet = receivedPacket.Packet;
Console.WriteLine($"Essential Packet: {packet.Type} (ID: {packet.Id})");
Console.WriteLine($" Session: {receivedPacket.SessionKey}");
Console.WriteLine($" Data Source: {receivedPacket.DataSource}");
Console.WriteLine($" Submit Time: {receivedPacket.SubmitTime}");
Console.WriteLine($" Stream: {receivedPacket.Stream}");
// Process based on packet type
switch (packet.Type)
{
case "Configuration":
HandleConfiguration(packet);
break;
case "Marker":
HandleMarker(packet);
break;
}
}
private void HandleConfiguration(Packet packet)
{
// Parse and process configuration packet
var configData = ConfigurationPacket.Parser.ParseFrom(packet.Content);
Console.WriteLine($"Configuration");
}
private void HandleMarker(Packet packet)
{
// Parse and process marker packet
var markerData = MarkerPacket.Parser.ParseFrom(packet.Content);
Console.WriteLine($"Marker");
}
}
// Usage
var handler = new EssentialPacketHandler();
essentialsService.AddHandler(handler);
```
### RemoveHandler
Removes a previously added handler.
```csharp
public void RemoveHandler(IHandler handler)
```
**Example:**
```csharp
essentialsService.RemoveHandler(handler);
```
### Initialise and Start
Initialize and start the essentials service.
```csharp
essentialsService.Initialise();
essentialsService.Start();
```
**Note**:
- `Initialise()` prepares the service and establishes connections
- `Start()` begins reading essential packets
- Essential packets are buffered and delivered to handlers asynchronously
### Stop
Stops the essentials service.
```csharp
essentialsService.Stop();
```
## Events
### ReadingEssentialsStarted
Fired when reading of essential packets begins for a session.
```csharp
essentialsService.ReadingEssentialsStarted += (sender, sessionInfo) =>
{
Console.WriteLine($"Started reading essentials for session: {sessionInfo.SessionKey}");
Console.WriteLine($"Data Source: {sessionInfo.DataSource}");
Console.WriteLine($"Session Type: {sessionInfo.Type}");
Console.WriteLine($"Historical: {sessionInfo.Historical}");
};
```
### ReadingEssentialsCompleted
Fired when reading of essential packets is complete.
```csharp
essentialsService.ReadingEssentialsCompleted += (sender, sessionInfo) =>
{
Console.WriteLine($"Completed reading essentials for session: {sessionInfo.SessionKey}");
Console.WriteLine($"Data Source: {sessionInfo.DataSource}");
};
```
## Complete Example
### Reading Essential Packets from a Session
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Shared.Abstractions;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.ReadingModule.Abstractions;
using MA.Streaming.OpenData;
// Create the Support Library API
var config = new StreamApiConfiguration(
kafkaConnection: "localhost:9092");
var supportLibApi = SupportLibApiFactory.CreateSupportLibApi(config);
// Get the Essentials API
var essentialsApi = supportLibApi.GetEssentialsApi();
// Create handler for essential packets
var essentialHandler = new EssentialPacketHandler();
// Create the essentials service
var serviceResult = essentialsApi.CreateService(
dataSource: "CarA",
sessionKey: "session-2026-02-26-001");
if (serviceResult.Success && serviceResult.Data != null)
{
var essentialsService = serviceResult.Data;
// Subscribe to events
essentialsService.ReadingEssentialsStarted += (s, sessionInfo) =>
{
Console.WriteLine($"Started reading essentials: {sessionInfo.SessionKey}");
};
essentialsService.ReadingEssentialsCompleted += (s, sessionInfo) =>
{
Console.WriteLine($"Completed reading essentials: {sessionInfo.SessionKey}");
};
// Add handler
essentialsService.AddHandler(essentialHandler);
// Initialize and start
essentialsService.Initialise();
essentialsService.Start();
// Wait for completion or stop manually
Console.WriteLine("Reading essential packets... Press any key to stop.");
Console.ReadKey();
// Stop the service
essentialsService.Stop();
}
else
{
Console.WriteLine($"Failed to create essentials service: {serviceResult.Message}");
}
```
## Architecture and Design
### Essential Stream
The Essentials Module reads from a dedicated "Essential" stream that contains:
- **Configuration Packets**: Session configuration and settings
- **Marker Packets**: Stream control and session markers
### Buffering Strategy
The module uses an unbounded auto-start buffer to handle essential packets efficiently:
- **Auto-Start Buffer**: Automatically begins processing when packets arrive
- **Unbounded**: No memory pressure constraints since essential packets are typically small
- **Asynchronous Processing**: Packets are buffered and processed asynchronously
### Lifecycle
1. **Service Creation**: Creates connection to the Essential stream
2. **Initialization**: Establishes connections and prepares handlers
3. **Start**: Begins reading from the Essential stream
4. **Packet Processing**: Essential packets are received and dispatched to handlers
5. **Completion**: Automatically detects when all essential packets are read
6. **Stop**: Cleans up resources and disconnections
## Best Practices
### 1. Use Before Full Data Processing (Historic Sessions Only)
Read essential packets before processing full session data to understand the session structure. **Note: This pattern applies to historic sessions only**, where all essentials are available upfront. For live sessions, essentials may still be arriving as the session progresses.
```csharp
// Step 1: Read essentials to get data formats
var essentialsService = essentialsApi.CreateService(dataSource, sessionKey).Data;
var formatCollector = new DataFormatCollector();
essentialsService.AddHandler(formatCollector);
essentialsService.Initialise();
essentialsService.Start();
// Wait for essentials to complete...
await formatCollector.WaitForCompletion();
// Step 2: Now process full data with format knowledge
var readerService = readerApi.CreateService(dataSource, sessionKey).Data;
// ... process full session data
```
### 2. Handle Multiple Session Essentials
You can create multiple essentials services for different sessions:
```csharp
var sessions = new[] { "session-001", "session-002", "session-003" };
var essentialsServices = sessions.Select(sessionKey =>
{
var service = essentialsApi.CreateService(dataSource, sessionKey).Data;
service.AddHandler(sharedHandler);
service.Initialise();
return service;
}).ToList();
// Start all services
essentialsServices.ForEach(s => s.Start());
// Wait for all to complete...
```
### 3. Error Handling
Always check API results and handle errors appropriately:
```csharp
var result = essentialsApi.CreateService(dataSource, sessionKey);
if (!result.Success || result.Data == null)
{
logger.Error($"Failed to create essentials service: {result.Message}");
// Handle error - session might not exist or be accessible
return;
}
var service = result.Data;
// Proceed with service usage...
```
### 4. Combine with Session Manager
Use with the Session Manager module to discover and process sessions:
```csharp
var sessionManager = supportLibApi.GetSessionManagerApi();
var sessions = sessionManager.GetSessions(dataSource).Data;
foreach (var session in sessions)
{
var essentialsService = essentialsApi.CreateService(
session.DataSource,
session.SessionKey).Data;
// Process essential packets for each session
essentialsService.AddHandler(essentialHandler);
essentialsService.Initialise();
essentialsService.Start();
}
```
## Differences from Reader Module
| Feature | Essentials Module | Reader Module |
|---------|-------------------|---------------|
| **Purpose** | Read essential/configuration packets only | Read all data packets |
| **Stream** | Reads from "Essential" stream | Reads from all session streams |
| **Data Volume** | Low (configuration data only) | High (all telemetry data) |
| **Use Case** | Metadata and configuration retrieval | Full session data processing |
| **Configuration** | Simple (data source + session key) | Complex (streams, filters, timeouts) |
| **Performance** | Lightweight and fast | Heavier, processes all data |
## Python FFI Support
The Essentials Module is also available through the Python FFI library:
```python
from contracts.essentials.i_essentials_service_module_api import IEssentialsServiceModuleApi
from core.essentials.essentials_service_module_api import EssentialsServiceModuleApi
# Get essentials API
essentials_api = support_lib_api.get_essentials_api()
# Create service
essentials_service = essentials_api.create_service(data_source, session_key)
# Add handler
essentials_service.add_handler(packet_handler)
# Initialize and start
essentials_service.initialise()
essentials_service.start()
```
## Related Modules
- **[Session Manager](session-manager.md)**: Discover sessions before reading essentials
- **[Reader Module](reader-module.md)**: Read full session data after essentials
- **[Data Format Manager](data-format-manager.md)**: Define formats that appear in essentials
---
# Buffering Module
## Overview
The Buffering Module, also known as the Sample Reader Module, is a component that pipelines with the Packet Reader Module. It buffers incoming packets, merges data segments, and extracts time-aligned samples from the raw packet stream. This module transforms packet-level data into sample-level data suitable for analysis and visualization.
## Key Features
- **Packet Buffering**: Buffer incoming packets in configurable time windows
- **Data Merging**: Merge data from multiple packets into coherent samples
- **Sample Extraction**: Extract time-aligned parameter samples
- **Sliding Window**: Process data with configurable sliding windows
- **Parameter Subscription**: Subscribe to specific parameters or all parameters
- **Dynamic Subscription**: Add/remove parameter subscriptions on-the-fly
- **Multiple Merge Strategies**: Support different merging approaches
- **Event Filtering**: Include/exclude markers, events, errors, and CAN data
- **Pipeline Architecture**: Seamlessly connects to Packet Reader output
## API Access
### Get the Sample Reader API
```csharp
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
```
### Create a Sample Reader Service
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.BufferingModule;
var config = new BufferingConfiguration(
subscribedParameters: new[] { "Speed", "RPM", "Throttle" },
bufferingWindowLength: 3000, // 3 seconds
slidingWindowPercentage: 5, // 5% slide
mergeStrategy: MergeStrategy.ReadingMerge, // better to use reading merge for performance
includeMarkerData: false,
includeEventData: false,
includeErrorData: false,
includeCanData: false);
var result = sampleReaderApi.CreateService(config);
if (result.Success && result.Data != null)
{
var sampleReaderService = result.Data;
}
```
## Configuration Options
### BufferingConfiguration
```csharp
public BufferingConfiguration(
IReadOnlyList? subscribedParameters = null,
uint? bufferingWindowLength = 3000,
uint? slidingWindowPercentage = 5,
MergeStrategy? mergeStrategy = null,
bool? includeMarkerData = null,
bool? includeEventData = null,
bool? includeErrorData = null,
bool? includeCanData = null,
bool? allowWildcardMatch = null)
```
**Parameters:**
- **subscribedParameters**: List of parameter identifiers to subscribe to
- `null` or empty list = no parameters initially subscribed
- Can subscribe/unsubscribe dynamically later
- Parameter names must match those defined in Data Format Manager
- Entries may contain the `*` wildcard, or regex syntax, when `allowWildcardMatch` is enabled — see [Wildcard and regex parameter matching](#wildcard-and-regex-parameter-matching)
- **bufferingWindowLength**: Length of buffering window in milliseconds (default: 3000ms = 3 seconds)
- Larger windows provide more context but increase latency
- Smaller windows reduce latency but may miss data correlations
- **slidingWindowPercentage**: Percentage of window to advance on each slide (default: 5%)
- Range: 1-100
- 5% = window slides by 5% of its length each iteration
- 100% = window jumps by full length (no overlap)
- Lower percentage = more overlap, smoother results, higher processing
- **mergeStrategy**: Strategy for merging data segments
- `MergeStrategy.ReadingMerge`: Default strategy optimized for reading
- Other strategies may be available based on implementation
- **includeMarkerData**: Include marker packets in buffering (default: false)
- **includeEventData**: Include event packets in buffering (default: false)
- **includeErrorData**: Include error packets in buffering (default: false)
- **includeCanData**: Include CAN bus data in buffering (default: false)
- **allowWildcardMatch**: Allow partial parameter matching using the `*` wildcard, or full regex syntax, in subscribed parameter names (default: true) — see [Wildcard and regex parameter matching](#wildcard-and-regex-parameter-matching)
### Wildcard and regex parameter matching
By default (`allowWildcardMatch: true`), entries in `subscribedParameters` — and identifiers passed to `Subscribe` at runtime — are matched using more than plain equality. Which matching strategy applies depends on what the entry looks like:
- **Plain identifiers** (no `*` and none of the regex characters below) are compared to the incoming identifier case-insensitively.
- **`*` wildcard patterns** match any sequence of characters, and are compared case-sensitively.
- **Patterns containing regex syntax** — any of `. $ ^ { [ ( | ) + ? \` — are compiled and matched as a real, case-sensitive regular expression, anchored to the whole identifier. This is the slowest of the three, so only reach for it when a `*` wildcard can't express what you need.
```csharp
var config = new BufferingConfiguration(
subscribedParameters: new[]
{
"Speed", // exact match, case-insensitive
"Brake*", // matches every parameter identifier starting with "Brake"
"Wheel[0-9]+", // regex fallback: matches Wheel0, Wheel12, ...
});
```
Matching rules:
- A pattern must match the **whole** incoming parameter identifier — `Brake*` matches `BrakeTemp` but `rake*` does not match `BrakeTemp`.
- Entries without `*` or regex syntax behave as an exact match, but that exact match is case-insensitive.
- Entries with `*` or regex syntax are matched case-sensitively.
!!! warning "Regex characters in identifiers are not escaped"
If a subscribed identifier contains a character from `. $ ^ { [ ( | ) + ? \`, it is compiled
as regex syntax rather than treated as a literal character. For example `Speed.Front` is not
matched literally — the `.` matches any single character. If your naming convention uses
these characters as literal text, avoid combining them with `*`/regex-style patterns, or
escape them yourself before passing them in.
Set `allowWildcardMatch: false` to treat every subscription as a literal identifier compared case-sensitively, including any that contain `*` or regex syntax.
```csharp
public enum MergeStrategy
{
WritingMerge,
ReadingMerge // Optimized for sequential reading and merging
}
```
## Methods
### SetReaderService
Connects the sample reader to a packet reader service.
```csharp
public void SetReaderService(IPacketReaderService readingService)
```
**Example:**
```csharp
// Create packet reader
var packetReaderService = readerApi.CreateService(dataSource, sessionKey).Data;
// Create sample reader
var sampleReaderService = sampleReaderApi.CreateService(bufferingConfig).Data;
// Pipeline them together
sampleReaderService.SetReaderService(packetReaderService);
// Initialize both
packetReaderService.Initialise();
sampleReaderService.Initialise();
// Start both (order matters: start packet reader last)
sampleReaderService.Start();
packetReaderService.Start();
```
### AddHandler (Timestamp Data)
Adds a handler for timestamp data (merged samples).
```csharp
public void AddHandler(IHandler timestampHandler)
```
**Example:**
```csharp
public class TimestampDataHandler : IHandler
{
public void Handle(ITimestampData data)
{
Console.WriteLine($"Start Timestamp: {data.TimeColumns[0].Timestamp}");
Console.WriteLine($"Data Source: {data.DataSource}");
Console.WriteLine($"Session: {data.SessionKey}");
foreach (var column in data.TimeColumns)
{
Console.WriteLine($" Timestamp: {column.Timestamp}");
Console.WriteLine($" Samples: {column.SampleValues.Count}");
foreach (var sample in column.SampleValues)
{
Console.WriteLine($" Parameter Identifier:{sample.Identifier} Value: {sample.Value} at {column.Timestamp}");
}
}
// Check if this is the end marker
if (data is EndTimestampData)
{
Console.WriteLine("End of session data");
}
}
}
var handler = new TimestampDataHandler();
sampleReaderService.AddHandler(handler);
```
### AddHandler (Sample Data)
Adds a handler for sample data (alternative data format). It contains all values for each parameter in that reading range, with values ordered per parameter but not time-aligned across parameters.
```csharp
public void AddHandler(IHandler sampleHandler)
```
### RemoveHandler
Removes previously added handlers.
```csharp
public void RemoveHandler(IHandler timestampHandler);
public void RemoveHandler(IHandler sampleHandler);
```
### Subscribe
Subscribes to specific parameters.
```csharp
public void Subscribe(IEnumerable parameterIdentifiers)
```
**Example:**
```csharp
// Subscribe to additional parameters
sampleReaderService.Subscribe(new[] { "BrakePressure", "SteeringAngle" });
```
**Note**: Can be called before or during data processing for dynamic subscription. There is a limitation on the number of parameters that can be merged simultaneously. To maintain optimal live processing performance, avoid subscribing to an excessive number of parameters, as merging operations may be constrained by system resources and processing capabilities.
### Unsubscribe
Unsubscribes from specific parameters.
```csharp
public void Unsubscribe(IEnumerable parameterIdentifiers)
```
**Example:**
```csharp
sampleReaderService.Unsubscribe(new[] { "Throttle" });
```
### UnsubscribeAll
Unsubscribes from all parameters.
```csharp
public void UnsubscribeAll()
```
### GetLastTimeInfo
Gets the last timestamp information for each stream.
```csharp
public IReadOnlyList<(string Stream, ulong LastTimestamp)> GetLastTimeInfo(
string dataSource,
string sessionKey)
```
**Example:**
```csharp
var timeInfo = sampleReaderService.GetLastTimeInfo(dataSource, sessionKey);
foreach (var (stream, lastTimestamp) in timeInfo)
{
Console.WriteLine($"Stream: {stream}, Last Timestamp: {lastTimestamp}µs");
}
```
## Events
### SessionDataMergingStarted
Fired when sample merging starts for a session.
```csharp
sampleReaderService.SessionDataMergingStarted += (sender, sessionInfo) =>
{
Console.WriteLine($"Started merging data for session: {sessionInfo.SessionKey}");
Console.WriteLine($"Session Type: {sessionInfo.Type}");
};
```
### SessionDataMergingCompleted
Fired when sample merging completes for a session.
```csharp
sampleReaderService.SessionDataMergingCompleted += (sender, sessionInfo) =>
{
Console.WriteLine($"Completed merging data for session: {sessionInfo.SessionKey}");
Console.WriteLine($"Historical: {sessionInfo.Historical}");
};
```
## Data Structures
### ITimestampData
Represents merged sample data at a specific timestamp.
```csharp
public interface ITimestampData
{
string DataSource { get; }
string SessionKey { get; }
ulong StartTime { get; }
ulong EndTime { get; }
IReadOnlyList TimeColumns { get; }
}
```
### ITimeColumn
Represents sample values for a single parameter.
```csharp
public interface ITimestampColumn
{
ulong Timestamp { get; }
IReadOnlyList SampleValues { get; }
}
```
### ISampleValue
Represents a single sample value.
```csharp
public interface ISampleValue
{
string Identifier { get; }
IGenericValue Value { get; }
ValueStatus Status { get; }
Type ValueType { get; }
T? Cast();
}
```
### EndTimestampData
Special marker indicating end of session data and merging.
```csharp
if (data is EndTimestampData)
{
// Session data processing complete
}
```
## Complete Examples
### Example 1: Basic Buffering Pipeline
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.BufferingModule;
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.BufferingModule.Abstractions;
public class BasicBufferingExample
{
public void SetupBufferingPipeline(
ISupportLibApi supportLibApi,
string dataSource,
string sessionKey)
{
// 1. Create packet reader
var readerApi = supportLibApi.GetReadingPacketApi();
var packetReaderResult = readerApi.CreateService(dataSource, sessionKey);
var packetReaderService = packetReaderResult.Data;
// 2. Create sample reader with configuration
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
var bufferingConfig = new BufferingConfiguration(
subscribedParameters: new[] {
"Speed",
"RPM",
"Throttle",
"BrakePressure"
},
bufferingWindowLength: 5000, // 5 second window
slidingWindowPercentage: 10); // 10% slide
var sampleReaderResult = sampleReaderApi.CreateService(bufferingConfig);
var sampleReaderService = sampleReaderResult.Data;
// 3. Connect them
sampleReaderService.SetReaderService(packetReaderService);
// 4. Add handler
sampleReaderService.AddHandler(new SampleProcessor());
// 5. Subscribe to events
sampleReaderService.SessionDataMergingStarted += (s, session) =>
{
Console.WriteLine($"Merging started for {session.SessionKey}");
};
sampleReaderService.SessionDataMergingCompleted += (s, session) =>
{
Console.WriteLine($"Merging completed for {session.SessionKey}");
};
// 6. Initialize and start
packetReaderService.Initialise();
sampleReaderService.Initialise();
sampleReaderService.Start();
packetReaderService.Start(); // Start packet reader last
// Wait for completion...
}
private class SampleProcessor : IHandler
{
private int sampleCount = 0;
public void Handle(ITimestampData data)
{
if (data is EndTimestampData)
{
Console.WriteLine($"Total samples processed: {this.sampleCount}");
return;
}
foreach (var column in data.TimeColumns)
{
this.sampleCount += column.SampleValues.Count;
Console.WriteLine($"#Sample {column.SampleValues.Count} at {column.Timestamp}");
}
}
}
}
```
### Example 2: Dynamic On-the-Fly Subscription
```csharp
public class DynamicSubscriptionExample
{
private ISampleReaderService sampleReaderService;
private HashSet currentSubscriptions = new();
public void SetupDynamicSubscription(ISupportLibApi supportLibApi)
{
// Create with no initial subscriptions
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
var config = new BufferingConfiguration(); // Empty subscription list
var result = sampleReaderApi.CreateService(config);
sampleReaderService = result.Data;
// Add handler
sampleReaderService.AddHandler(new DynamicSampleHandler());
// Start with no subscriptions, add them dynamically
Task.Run(() => ManageSubscriptionsAsync());
}
private async Task ManageSubscriptionsAsync()
{
await Task.Delay(1000);
// Subscribe to initial set
Console.WriteLine("Subscribing to Speed and RPM");
SubscribeTo(new[] { "Speed", "RPM" });
await Task.Delay(5000);
// Add more parameters
Console.WriteLine("Adding Throttle and BrakePressure");
SubscribeTo(new[] { "Throttle", "BrakePressure" });
await Task.Delay(5000);
// Remove a parameter
Console.WriteLine("Removing RPM");
UnsubscribeFrom(new[] { "RPM" });
}
private void SubscribeTo(string[] parameters)
{
sampleReaderService.Subscribe(parameters);
foreach (var param in parameters)
{
currentSubscriptions.Add(param);
}
}
private void UnsubscribeFrom(string[] parameters)
{
sampleReaderService.Unsubscribe(parameters);
foreach (var param in parameters)
{
currentSubscriptions.Remove(param);
}
}
private class DynamicSampleHandler : IHandler
{
public void Handle(ITimestampData data)
{
if (data is EndTimestampData) return;
var receivedParams = data.TimeColumns.SelectMany(c => c.SampleValues.Select(sv=>sv.Identifier)).ToList();
Console.WriteLine($"Received parameters: {string.Join(", ", receivedParams)}");
}
}
}
```
### Example 3: Advanced Sample Analysis
```csharp
public class SampleAnalyzer : IHandler
{
private readonly Dictionary> parameterValues = new();
private readonly Dictionary ranges = new();
public void Handle(ITimestampData data)
{
if (data is EndTimestampData)
{
PrintSummary();
return;
}
foreach (var column in data.TimeColumns)
{
foreach (var sample in column.SampleValues)
{
if (!parameterValues.ContainsKey(sample.Identifier))
{
parameterValues[sample.Identifier] = [];
ranges[sample.Identifier] = (double.MaxValue, double.MinValue);
}
if (sample.Value.ValueType==typeof(double))
{
var value = sample.Value.Cast();
parameterValues[sample.Identifier].Add(value);
var (min, max) = ranges[sample.Identifier];
ranges[sample.Identifier] = (
Math.Min(min, value),
Math.Max(max, value)
);
}
}
}
}
private void PrintSummary()
{
Console.WriteLine("\n=== Sample Analysis Summary ===");
foreach (var param in parameterValues.Keys)
{
var values = parameterValues[param];
var (min, max) = ranges[param];
var avg = values.Average();
Console.WriteLine($"\nParameter: {param}");
Console.WriteLine($" Samples: {values.Count}");
Console.WriteLine($" Min: {min:F2}");
Console.WriteLine($" Max: {max:F2}");
Console.WriteLine($" Avg: {avg:F2}");
}
}
}
```
### Example 4: Buffering with Events and Markers
```csharp
public void SetupWithEventsAndMarkers(ISupportLibApi supportLibApi)
{
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
// Configure to include events and markers
var config = new BufferingConfiguration(
subscribedParameters: new[] { "Speed", "RPM" },
bufferingWindowLength: 3000,
slidingWindowPercentage: 5,
includeMarkerData: true, // Include markers
includeEventData: true); // Include events
var result = sampleReaderApi.CreateService(config);
var sampleReaderService = result.Data;
sampleReaderService.AddHandler(new SampleHandler());
// Setup pipeline and start...
}
```
## Working with Generic Values
### Extracting Values from IGenericValue
Use the `ValueType` property to check the type, then use `Cast()` to extract the value:
```csharp
public object? ExtractValue(IGenericValue genericValue)
{
if (genericValue.ValueType == typeof(double))
return genericValue.Cast();
if (genericValue.ValueType == typeof(MarkerData))
return genericValue.Cast();
if (genericValue.ValueType == typeof(EventData))
return genericValue.Cast();
if (genericValue.ValueType == typeof(ErrorData))
return genericValue.Cast();
if (genericValue.ValueType == typeof(CanData))
return genericValue.Cast();
return null;
}
```
## Best Practices
1. **Configure Window Size Appropriately**:
- Larger windows for analysis requiring more context
- Smaller windows for low-latency applications
2. **Optimize Sliding Percentage**:
- Lower percentage (10-20%) for smooth, continuous analysis
- Higher percentage (50-100%) for distinct chunks with less overlap
3. **Subscribe Selectively**:
- Only subscribe to parameters you need to reduce memory and processing
- Use dynamic subscription to adapt to changing requirements
4. **Pipeline Order Matters**:
- Always initialize services before starting
- Start sample reader before packet reader
- Stop in reverse order
5. **Handle End Markers**: Always check for `EndTimestampData` to detect completion
6. **Thread Safety**: Handlers may be called from different threads. Create separate handler instances for each sample reader service rather than sharing a single handler instance across multiple services to avoid concurrency issues and ensure proper isolation of processing logic.
7. **Memory Management**: Unsubscribe from parameters you no longer need
8. **Event Filtering**: Only include events/markers/CAN data if needed
## Performance Tuning
### For Real-Time Processing
```csharp
var realtimeConfig = new BufferingConfiguration(
subscribedParameters: criticalParameters,
bufferingWindowLength: 3000, // 3 second
slidingWindowPercentage: 10, // 20% slide for lower latency
includeMarkerData: false,
includeEventData: false);
```
### For Analysis/Playback
```csharp
var analysisConfig = new BufferingConfiguration(
subscribedParameters: null, // Subscribe dynamically
bufferingWindowLength: 20000, // 20 seconds
slidingWindowPercentage: 5, // 5% for maximum overlap
includeMarkerData: true,
includeEventData: true);
```
## Common Issues and Solutions
### Issue: Missing Samples
**Solution**: Increase `bufferingWindowLength` to capture more data in each window.
### Issue: High Latency
**Solution**: Decrease `bufferingWindowLength` or increase `slidingWindowPercentage`.
### Issue: High Memory Usage
**Solution**: Reduce subscribed parameters or decrease window length.
## See Also
- [Reader Module](reader-module.md)
- [Essentials Module](essentials-module.md)
- [Interpolation Module](interpolation-module.md)
- [API Reference](api-reference.md)
---
# Interpolation Module
## Overview
The Interpolation Module, also known as the Data Reader or Data API Module, provides data by subscribing to parameters at custom frequencies and performing automatic interpolation or decimation. This module pipelines with the Sample Reader output and enables applications to receive data at their desired sampling rates regardless of the original data frequency.
## Key Features
- **Custom Frequency Subscriptions**: Subscribe to parameters at any desired frequency
- **Automatic Interpolation**: Super-sample lower frequency data to higher frequencies
- **Automatic Decimation**: Sub-sample higher frequency data to lower frequencies
- **Batch Result Delivery**: Receive results in configurable batches
- **Multiple Subscriptions**: Manage multiple subscriptions with different frequencies
- **Subscription Processors**: Apply custom processing logic to subscriptions
- **Dynamic Management**: Add and remove subscriptions on-the-fly
- **Pipeline Integration**: Seamlessly connects to Sample Reader output
## API Access
### Get the Data Reader API
```csharp
var dataReaderApi = supportLibApi.GetDataReaderApi();
```
### Create a Data Reader Service
```csharp
var result = dataReaderApi.CreateService();
if (result.Success && result.Data != null)
{
var dataReaderService = result.Data;
}
```
**Note**: Unlike other services, the Data Reader has no configuration at creation time. All configuration is done through subscriptions.
## Core Concepts
### Subscription Model
Each subscription specifies:
- **Subscription Key**: Unique identifier for the subscription
- **Parameters**: List of parameter identifiers to include
- **Subscription Frequency**: Target frequency in Hz (samples per second)
- **Delivery Frequency**: How often to deliver batched results (optional)
- **Handler**: Callback to receive interpolated results
- **Processor**: Optional custom processing logic
### Interpolation vs. Decimation
- **Super-sampling (Interpolation)**: When subscription frequency > original data frequency
- Data is interpolated to fill gaps
- Creates smooth transitions between known values
- **Sub-sampling (Decimation)**: When subscription frequency < original data frequency
- Data is decimated to reduce sample count
- Selects or averages samples to match target frequency
## Methods
### SetSampleReaderService
Connects the data reader to a sample reader service.
```csharp
public void SetSampleReaderService(ISampleReaderService sampleReaderService)
```
**Example:**
```csharp
// Create the pipeline: PacketReader -> SampleReader -> DataReader
// 1. Create packet reader
var packetReaderService = readerApi.CreateService(dataSource, sessionKey).Data;
// 2. Create sample reader
var sampleReaderService = sampleReaderApi.CreateService(bufferingConfig).Data;
// 3. Create data reader
var dataReaderService = dataReaderApi.CreateService().Data;
// 4. Connect the pipeline
sampleReaderService.SetReaderService(packetReaderService);
dataReaderService.SetSampleReaderService(sampleReaderService);
// 5. Initialize and start (in order)
packetReaderService.Initialise();
sampleReaderService.Initialise();
dataReaderService.Initialise();
dataReaderService.Start();
sampleReaderService.Start();
packetReaderService.Start();
```
### Subscribe
Creates a new subscription for interpolated data.
```csharp
public void Subscribe(
string subscriptionKey,
IReadOnlyList parameterIdentifiers,
double subscriptionFrequencyHz,
IBatchResultHandler handler,
double? deliveryFrequencyHz = null,
ISubscriptionProcessor? processor = null)
```
**Parameters:**
- **subscriptionKey**: Unique identifier for this subscription (used to unsubscribe later)
- **parameterIdentifiers**: List of parameter names to include in results
- **subscriptionFrequencyHz**: Target sampling frequency in Hz (e.g., 10.0 = 10 samples/second)
- **deliveryFrequencyHz**: (Optional) How often to deliver batched results in Hz (default: 10.0)
- If not specified, defaults to 10 Hz (10 deliveries per second)
- If specified, results are batched and delivered at this frequency
- Should not be set to 0
- **processor**: (Optional) Custom processor for additional data transformation
**Example:**
```csharp
// Subscribe to parameters at 100 Hz with results delivered every 10 Hz
dataReaderService.Subscribe(
subscriptionKey: "TelemetryData_100Hz",
parameterIdentifiers: new[] { "Speed", "RPM", "Throttle", "BrakePressure" },
subscriptionFrequencyHz: 100.0, // Want 100 samples per second
handler: new MyBatchResultHandler(),
deliveryFrequencyHz: 10.0); // Deliver batches 10 times per second
```
### Unsubscribe
Removes a subscription.
```csharp
public void Unsubscribe(string subscriptionKey)
```
**Example:**
```csharp
dataReaderService.Unsubscribe("TelemetryData_100Hz");
```
## Handlers
### IBatchResultHandler Interface
Implement this interface to receive interpolation results.
```csharp
public interface IBatchResultHandler
{
void Handle(BatchResult result);
}
```
### BatchResult
Contains the interpolated results for a batch.
```csharp
public class BatchResult
{
public readonly string DataSource;
public readonly string SubscriptionKey;
public readonly string SessionKey;
public readonly ulong DeliveryIntervalStartTimeNano;
public readonly ulong DeliveryIntervalEndTimeNano;
public readonly IReadOnlyList Results;
}
```
**Properties:**
- **DataSource**: The data source identifier
- **SubscriptionKey**: Unique identifier for the subscription
- **SessionKey**: Session identifier for the data
- **DeliveryIntervalStartTimeNano**: Start timestamp of the delivery interval in nanoseconds
- **DeliveryIntervalEndTimeNano**: End timestamp of the delivery interval in nanoseconds
- **Results**: Collection of interpolated results in this batch
### IProcessResult
Individual interpolation result.
```csharp
public interface IProcessResult
{
string Identifier { get; }
ulong IntervalStartTimeNano { get; }
ulong IntervalEndTimeNano { get; }
}
```
**Properties:**
- **Identifier**: parameter identifier
- **IntervalStartTimeNano**: Start timestamp of the interval in nanoseconds
- **IntervalEndTimeNano**: End timestamp of the interval in nanoseconds
## Complete Examples
### Example 1: Basic Interpolation
```csharp
using MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.InterpolationModule.Abstractions;
public class BasicInterpolationExample
{
public void SetupInterpolation(ISupportLibApi supportLibApi, string dataSource, string sessionKey)
{
// 1. Create the full pipeline
var readerApi = supportLibApi.GetReadingPacketApi();
var packetReaderService = readerApi.CreateService(dataSource, sessionKey).Data;
var sampleReaderApi = supportLibApi.GetSampleReaderApi();
var bufferingConfig = new BufferingConfiguration(
subscribedParameters: new[] { "Speed", "RPM", "Throttle" });
var sampleReaderService = sampleReaderApi.CreateService(bufferingConfig).Data;
var dataReaderApi = supportLibApi.GetDataReaderApi();
var dataReaderService = dataReaderApi.CreateService().Data;
// 2. Connect pipeline
sampleReaderService.SetReaderService(packetReaderService);
dataReaderService.SetSampleReaderService(sampleReaderService);
// 3. Create subscription
dataReaderService.Subscribe(
subscriptionKey: "MainTelemetry",
parameterIdentifiers: new[] { "Speed", "RPM", "Throttle" },
subscriptionFrequencyHz: 50.0, // 50 Hz output
handler: new InterpolationHandler(),
deliveryFrequencyHz: 10.0); // Deliver 10 times per second
// 4. Initialize and start
packetReaderService.Initialise();
sampleReaderService.Initialise();
dataReaderService.Initialise();
dataReaderService.Start();
sampleReaderService.Start();
packetReaderService.Start();
}
private class InterpolationHandler : IBatchResultHandler
{
private int batchCount = 0;
public void Handle(BatchResult result)
{
batchCount++;
Console.WriteLine($"\n=== Batch {batchCount} ===");
Console.WriteLine($"Subscription: {result.SubscriptionKey}");
Console.WriteLine($"Session: {result.SessionKey}");
Console.WriteLine($"Data Source: {result.DataSource}");
Console.WriteLine($"Interval: {result.DeliveryIntervalStartTimeNano}ns - {result.DeliveryIntervalEndTimeNano}ns");
Console.WriteLine($"Results: {result.Results.Count}");
foreach (var processResult in result.Results)
{
Console.WriteLine($" Parameter: {processResult.Identifier}");
Console.WriteLine($" Interval: {processResult.IntervalStartTimeNano}ns - {processResult.IntervalEndTimeNano}ns");
}
}
}
}
```
### Example 2: Multiple Subscriptions at Different Frequencies
```csharp
public class MultiFrequencyExample
{
private IDataReaderService dataReaderService;
public void SetupMultipleSubscriptions(IDataReaderService dataReaderService)
{
this.dataReaderService = dataReaderService;
// High frequency subscription for critical parameters
dataReaderService.Subscribe(
subscriptionKey: "HighFreq_Critical",
parameterIdentifiers: new[] { "Speed", "BrakePressure", "ThrottlePosition" },
subscriptionFrequencyHz: 200.0, // 200 Hz
handler: new HighFrequencyHandler(),
deliveryFrequencyHz: 20.0);
// Medium frequency for engine data
dataReaderService.Subscribe(
subscriptionKey: "MediumFreq_Engine",
parameterIdentifiers: new[] { "RPM", "EngineTemp", "OilPressure" },
subscriptionFrequencyHz: 50.0, // 50 Hz
handler: new MediumFrequencyHandler(),
deliveryFrequencyHz: 10.0);
// Low frequency for slowly changing parameters
dataReaderService.Subscribe(
subscriptionKey: "LowFreq_Ambient",
parameterIdentifiers: new[] { "AmbientTemp", "TrackTemp", "Humidity" },
subscriptionFrequencyHz: 1.0, // 1 Hz
handler: new LowFrequencyHandler(),
deliveryFrequencyHz: 1.0);
}
private class HighFrequencyHandler : IBatchResultHandler
{
public void Handle(BatchResult result)
{
// Process high-frequency critical data
Console.WriteLine($"[200Hz] Received {result.Results.Count} samples");
}
}
private class MediumFrequencyHandler : IBatchResultHandler
{
public void Handle(BatchResult result)
{
// Process medium-frequency engine data
Console.WriteLine($"[50Hz] Received {result.Results.Count} samples");
}
}
private class LowFrequencyHandler : IBatchResultHandler
{
public void Handle(BatchResult result)
{
// Process low-frequency ambient data
Console.WriteLine($"[1Hz] Received {result.Results.Count} samples");
}
}
}
```
## Best Practices
1. **Choose Appropriate Frequencies**:
- Higher frequencies = more data, higher processing cost
- Match frequency to your actual needs (display update rate, analysis requirements)
2. **Use Delivery Frequency Wisely**:
- Batching results reduces handler call overhead
- Balance between latency and efficiency
3. **Subscription Keys**:
- Use descriptive keys for easier management
- Follow a naming convention (e.g., "Feature_Frequency_Purpose")
4. **Pipeline Order**:
- Always set up the full pipeline before starting
- Initialize in order: Packet -> Sample -> Data
- Start in reverse order: Data -> Sample -> Packet
5. **Resource Management**:
- Unsubscribe from subscriptions you no longer need
- Close file handles and dispose resources in handlers
6. **Error Handling**:
- Wrap handler logic in try-catch to prevent crashes
- Log errors for debugging
## Performance Considerations
### Interpolation Overhead
- Higher subscription frequencies require more interpolation calculations
- Consider the original data frequency vs. desired output frequency
- Large frequency mismatches increase processing load
### Delivery Frequency Optimization
```csharp
// High overhead - handler called very frequently
dataReaderService.Subscribe("Sub1", params, 100.0, handler, deliveryFrequencyHz: 100.0);
// Optimized - results batched, handler called less frequently
dataReaderService.Subscribe("Sub2", params, 100.0, handler, deliveryFrequencyHz: 10.0);
```
### Memory Management
- Batched results accumulate in memory until delivered
- Very low delivery frequencies with high subscription frequencies may use significant memory
- Balance batch size with available memory
## See Also
- [Buffering Module](buffering-module.md)
- [Reader Module](reader-module.md)
- [API Reference](api-reference.md)
---
# API Reference
## Overview
This document provides a comprehensive reference for all public APIs, interfaces, and types in the MA DataPlatforms Streaming Support Library.
## Namespace Organization
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Abstractions` - Core abstractions and factory
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.SessionInfoModule` - Session management
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.DataFormatInfoModule` - Data format management
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.WritingModule` - Packet writing
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.ReadingModule` - Packet reading
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.Essentials` - Essential packet reading
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.BufferingModule` - Sample buffering
- `MA.DataPlatforms.Streaming.Support.Lib.Core.Contracts.InterpolationModule` - Data interpolation
---
## Core API
### ISupportLibApi
Main entry point for the support library.
```csharp
public interface ISupportLibApi : IServiceModel
{
ISessionManagerModuleApi? GetSessionManagerApi();
IDataFormatManagerModuleApi? GetDataFormatManagerApi();
IPacketWritingModuleApi? GetWritingPacketApi();
IPacketReadingModuleApi? GetReadingPacketApi();
IEssentialsModuleApi? GetEssentialsApi();
ISampleReadingModuleApi? GetSampleReaderApi();
IDataReadingModuleApi? GetDataReaderApi();
event EventHandler? Initialised;
bool IsInitialised { get; }
Task InitialiseAsync(CancellationToken cancellationToken);
void Initialise();
void Start();
void Stop();
}
```
### SupportLibApiFactory
Factory for creating support library instances.
```csharp
public class SupportLibApiFactory : ISupportLibApiFactory
{
public ISupportLibApi Create(
ILogger logger,
StreamingApiConfiguration streamingApiConfiguration,
RetryPolicy retryPolicy);
}
```
### ApiResult
Standard result wrapper for all API calls.
```csharp
public class ApiResult
{
public bool Success { get; }
public string Message { get; }
public T? Data { get; }
}
```
### IServiceModel
Base interface for all services.
```csharp
public interface IServiceModel : IDisposable
{
event EventHandler? Initialised;
event EventHandler? Started;
event EventHandler? Stopped;
bool IsInitialised { get; }
bool IsStarted { get; }
void Initialise();
Task InitialiseAsync(CancellationToken cancellationToken);
void Start();
void Stop();
}
```
---
## Session Manager Module
### ISessionManagerModuleApi
```csharp
public interface ISessionManagerModuleApi : IModuleApi
{
ApiResult CreateService();
}
```
### ISessionManagementService
```csharp
public interface ISessionManagementService : IModuleApiService
{
// Events
event EventHandler? LiveSessionStateChange;
event EventHandler? LiveSessionStarted;
event EventHandler? LiveSessionEnded;
event EventHandler? NewAssociationDetected;
// Properties
Guid Id { get; }
// Methods
ApiResult> GetAllSessions();
ApiResult CreateNewSession(SessionCreationDto createSessionDto);
ApiResult UpdateIdentifier(string dataSource, string sessionKey, string newIdentifier);
ApiResult AddAssociateSession(string dataSource, string sessionKey, string addingAssociateKey);
ApiResult UpdateSessionDetails(string dataSource, string sessionKey, IReadOnlyList sessionDetails);
ApiResult GetSessionInfo(string dataSource, string sessionKey);
ApiResult EndSession(string dataSource, string sessionKey);
}
```
### ISessionInfo
```csharp
public interface ISessionInfo
{
string SessionKey { get; }
string DataSource { get; }
string Identifier { get; }
string Type { get; }
uint Version { get; }
bool Historical { get; }
TimeSpan UtcOffset { get; }
IReadOnlyDictionary Details { get; }
IReadOnlyList AssociateSessionKeys { get; }
}
```
### SessionCreationDto
```csharp
public class SessionCreationDto
{
public readonly string DataSource;
public readonly string Identifier;
public readonly string Type;
public readonly uint Version;
public readonly TimeSpan UtcOffset;
public readonly IReadOnlyList Details;
public readonly IReadOnlyList AssociatedSessionKeys;
public SessionCreationDto(
string dataSource = "Default",
string identifier = "",
string type = "Session",
uint version = 1,
TimeSpan? utcOffset = null,
IReadOnlyList? details = null,
IReadOnlyList? associatedSessionKeys = null);
}
```
### SessionDetailDto
```csharp
public class SessionDetailDto
{
public readonly string Key;
public readonly string Value;
public SessionDetailDto(string key, string value);
}
```
### ISessionAssociationInfo
```csharp
public interface ISessionAssociationInfo
{
ISessionInfo MainSessionInfo { get; }
ISessionInfo AssociateSessionInfo { get; }
string Group { get; }
}
```
---
## Data Format Manager Module
### IDataFormatManagerModuleApi
```csharp
public interface IDataFormatManagerModuleApi : IModuleApi
{
ApiResult CreateService();
}
```
### IDataFormatManagementService
```csharp
public interface IDataFormatManagementService : IModuleApiService
{
// Events
event EventHandler DataFormatInfoUpdated;
// Methods
ApiResult GetEventDataFormatId(string dataSource, string eventName);
ApiResult GetEvent(string dataSource, ulong dataFormatId);
ApiResult GetParameterDataFormatId(string dataSource, IReadOnlyList parameterList);
ApiResult GetParametersList(string dataSource, ulong dataFormatId);
ApiResult?> GetDataSourceDataFormatInfo(string dataSource);
}
```
### DataFormatInfo
```csharp
public class DataFormatInfo
{
public string DataSource { get; }
public string Key { get; }
public IReadOnlyList DataFormats { get; }
public IReadOnlyList Identifiers { get; }
public DataFormatInfoType DataFormatInfoType { get; }
}
```
### ParameterDataFormatInfo
```csharp
public class ParameterDataFormatInfo
{
public readonly string DataSource;
public IReadOnlyList ParameterList;
public readonly ulong DataFormatId;
}
```
### EventDataFormatInfo
```csharp
public class EventDataFormatInfo
{
public readonly string DataSource;
public ulong DataFormatId;
public string EventName;
}
```
### DataFormatInfoType
```csharp
public enum DataFormatInfoType
{
Parameters,
Event
}
```
---
## Writer Module
### IPacketWritingModuleApi
```csharp
public interface IPacketWritingModuleApi : IModuleApi
{
ApiResult CreateService();
}
```
### IPacketWriterService
```csharp
public interface IPacketWriterService : IModuleApiService
{
ApiResult WriteData(string dataSource, string stream, string sessionKey, Packet packet);
ApiResult WriteInfo(Packet packet, InfoType infoType = InfoType.SessionInfo);
}
```
### InfoType
```csharp
public enum InfoType
{
Unspecified,
SessionInfo,
SystemStatus
}
```
---
## Essentials Module
### IEssentialsModuleApi
```csharp
public interface IEssentialsModuleApi : IModuleApi
{
ApiResult CreateService(string dataSource, string sessionKey);
}
```
### IEssentialsService
```csharp
public interface IEssentialsService : IModuleApiService
{
// Events
event EventHandler ReadingEssentialsStarted;
event EventHandler ReadingEssentialsCompleted;
// Properties
string DataSource { get; }
string SessionKey { get; }
// Methods
void AddHandler(IHandler handler);
void RemoveHandler(IHandler handler);
}
```
**Description**: The Essentials Module provides access to essential session packets such as configuration data, data format definitions, and session metadata. It reads from the dedicated "Essential" stream which contains critical session information without the overhead of processing full telemetry data. The lifecycle of the Essentials service is tied to the session lifecycle—it starts when the session begins and completes when all essential packets have been read or the session ends.
---
## Reader Module
### IPacketReadingModuleApi
```csharp
public interface IPacketReadingModuleApi : IModuleApi
{
ApiResult CreateService(string dataSource, string sessionKey);
ApiResult CreateService(IPacketReadingConfiguration config);
}
```
### IPacketReaderService
```csharp
public interface IPacketReaderService : IModuleApiService
{
// Events
event EventHandler SessionReadingStarted;
event EventHandler SessionReadingCompleted;
event EventHandler StreamReadingStarted;
event EventHandler StreamReadingCompleted;
event EventHandler SessionInfoUpdated;
event EventHandler SessionAssociationInfoUpdated;
event EventHandler CoverageCursorReceived;
// Properties
Guid Id { get; }
// Methods
void AddHandler(IHandler handler);
void RemoveHandler(IHandler handler);
}
```
### PacketReadingConfiguration
```csharp
public class PacketReadingConfiguration : IPacketReadingConfiguration
{
public string SessionKey { get; }
public uint InactivityTimeoutSeconds { get; }
public bool ExcludeMainStream { get; }
public string DataSource { get; }
public string SessionIdentifierPattern { get; }
public ReadingType ReadingType { get; }
public IReadOnlyList Streams { get; }
public IReadOnlyList ExcludedStreams { get; }
public LiveReadingType LiveReadingType { get; }
public int BufferLength { get; }
public string GroupId { get; }
public PacketReadingConfiguration(
string? dataSource = "Default",
string? sessionIdentifierPattern = "*",
ReadingType? readingType = ReadingType.Live,
IReadOnlyList? streams = null,
bool? excludeMainStream = false,
uint? inactivityTimeoutSeconds = 30,
string? sessionKey = null,
LiveReadingType? liveReadingType = null,
int? bufferLength = null,
string? groupId = null,
IReadOnlyList? excludedStreams = null);
}
```
### ReadingType
```csharp
public enum ReadingType
{
Live = 0,
Historic = 1,
Both = 2
}
```
### LiveReadingType
```csharp
public enum LiveReadingType
{
FromBeginning = 0, // Read live session from the beginning
LeadingEdge = 1 // Read live session from current point (skip past data)
}
```
### IReceivedPacketDto
```csharp
public interface IReceivedPacketDto
{
string DataSource { get; }
string SessionKey { get; }
Packet Packet { get; }
DateTime SubmitTime { get; }
string Stream { get; }
}
```
### IStreamInfo
```csharp
public interface IStreamInfo
{
string Stream { get; }
string SessionKey { get; }
string DataSource { get; }
}
```
### ICoverageCursorInfo
```csharp
public interface ICoverageCursorInfo
{
string DataSource { get; }
string SessionKey { get; }
ulong CoverageCursorTime { get; }
}
```
---
## Buffering Module
### ISampleReadingModuleApi
```csharp
public interface ISampleReadingModuleApi : IModuleApi
{
ApiResult CreateService(IBufferingConfiguration bufferingConfiguration);
}
```
### ISampleReaderService
```csharp
public interface ISampleReaderService : IModuleApiService
{
// Events
event EventHandler SessionDataMergingStarted;
event EventHandler SessionDataMergingCompleted;
// Properties
Guid Id { get; }
// Methods
void SetReaderService(IPacketReaderService readingService);
void AddHandler(IHandler timestampHandler);
void AddHandler(IHandler sampleHandler);
void RemoveHandler(IHandler timestampHandler);
void RemoveHandler(IHandler sampleHandler);
IReadOnlyList<(string Stream, ulong LastTimestamp)> GetLastTimeInfo(string dataSource, string sessionKey);
void Subscribe(IEnumerable parameterIdentifiers);
void SubscribeAll(); // Not recommended due to performance implications
void Unsubscribe(IEnumerable parameterIdentifiers);
void UnsubscribeAll();
}
```
### BufferingConfiguration
```csharp
public class BufferingConfiguration : IBufferingConfiguration
{
public bool IncludeMarkerData { get; }
public bool IncludeEventData { get; }
public bool IncludeErrorData { get; }
public bool IncludeCanData { get; }
public MergeStrategy MergeStrategy { get; }
public uint BufferingWindowLength { get; }
public uint SlidingWindowPercentage { get; }
public IReadOnlyList SubscribedParameters { get; }
public bool AllowWildcardMatch { get; }
public BufferingConfiguration(
IReadOnlyList? subscribedParameters = null,
uint? bufferingWindowLength = 3000,
uint? slidingWindowPercentage = 5,
MergeStrategy? mergeStrategy = null,
bool? includeMarkerData = null,
bool? includeEventData = null,
bool? includeErrorData = null,
bool? includeCanData = null,
bool? allowWildcardMatch = null);
}
```
### MergeStrategy
Defines the strategy for merging data packets.
```csharp
public enum MergeStrategy
{
WritingMerge = 0,
ReadingMerge = 1 // Default strategy; recommended for better performance
}
```
### ITimestampData
```csharp
public interface ITimestampData
{
string DataSource { get; }
string SessionKey { get; }
ulong Timestamp { get; }
IReadOnlyList TimeColumns { get; }
}
```
### ITimeColumn
```csharp
public interface ITimeColumn
{
ulong Timestamp { get; }
IReadOnlyList SampleValues { get; }
}
```
### ISampleValue
```csharp
public interface ISampleValue
{
string Identifier { get; }
IGenericValue Value { get; }
ValueStatus Status { get; }
Type ValueType { get; }
T? Cast();
}
```
### ISampleData
```csharp
public interface ISampleData
{
string DataSource { get; }
string SessionKey { get; }
ulong StartTime { get; }
ulong EndTime { get; }
string Identifier { get; }
IReadOnlyList Values { get; }
}
```
### ITimestampValue
```csharp
public interface ITimestampValue
{
ulong Timestamp { get; }
IGenericValue Value { get; }
ValueStatus Status { get; }
Type ValueType { get; }
T? Cast();
}
```
---
## Interpolation Module
### IDataReadingModuleApi
```csharp
public interface IDataReadingModuleApi : IModuleApi
{
ApiResult CreateService();
}
```
### IDataReaderService
```csharp
public interface IDataReaderService : IModuleApiService
{
// Properties
Guid Id { get; }
// Methods
void SetSampleReaderService(ISampleReaderService sampleReaderService);
void Subscribe(
string subscriptionKey,
IReadOnlyList