Live demo — data resets daily at 03:00 UTC. Nothing you enter is saved. Server UI →

product: maestro audience: test-developer authority: normative

Accordion Instrument Integration

This file covers the Maestro-specific integration pattern for test packages that communicate with an Accordion instrument via AccordionQ2.WebApiClient (.NET) or accordionq2 (Python).

For the full Accordion API reference — all endpoints, channel configuration, module management, bus transactions, and hardware models — see the dedicated Accordion docs:

  • Start here: ../Accordion/README.md
  • .NET API: ../Accordion/05-api-dotnet/
  • Python API: ../Accordion/05-api-python/

The integration pattern

Every test package that drives an Accordion instrument MUST follow this pattern:

  1. A Connect method/function is wired as a YAML setup: step with post_execution_action: terminate-on-fail. It receives the instrument host address from {{cfg.AGENT_HOST}} — never hard-coded.
  2. A Disconnect method/function is wired as a YAML teardown: step with run_on_abort: true, guaranteeing cleanup even on abort.
  3. The host address IS stored in Station Config under the key AGENT_HOST and referenced via {{cfg.AGENT_HOST}} — one YAML definition works on every station.

.NET — minimal connect / disconnect

using AccordionQ2.WebApiClient;

public class FunctionalTests
{
    static AccordionQ2Client client = null;

    public static void Connect(string host)
    {
        client = new AccordionQ2Client(host);
        client.Application.ResetAsync().Wait();
    }

    public static void Disconnect()
    {
        client?.Dispose();
        client = null;
    }
}

Corresponding YAML:

setup:
  - name: "Connect to instrument"
    runner: dotnet
    runner_type: net10.0
    assembly: "MyTests.dll"
    class: "MyTests.FunctionalTests"
    method: "Connect"
    parameters:
      host: "{{cfg.AGENT_HOST}}"
    post_execution_action: terminate-on-fail

teardown:
  - name: "Disconnect from instrument"
    runner: dotnet
    runner_type: net10.0
    assembly: "MyTests.dll"
    class: "MyTests.FunctionalTests"
    method: "Disconnect"
    run_on_abort: true

Python — minimal connect / disconnect

from accordionq2 import AccordionQ2Client

_client = None

def connect(host: str) -> None:
    global _client
    _client = AccordionQ2Client(host)
    _client.application.reset()

def disconnect() -> None:
    global _client
    if _client:
        _client.close()
        _client = None

Corresponding YAML — identical structure to the .NET example above, using runner: python, module:, and function: fields instead.

Station Config: instrument host address

The host address varies per test station. Store it in Station Config under any key and reference it via {{cfg.YOUR_KEY_NAME}} — never hard-code it.

The key name is yours to choose. AGENT_HOST is the convention used throughout the scaffold and documentation examples, but Accordion, ACCORDION_HOST, or any other name works equally well — what matters is that the key name in Station Config matches the {{cfg.KEY_NAME}} reference in your YAML exactly.

Tip: Use get_merged_config (MCP) or the TAT UI → Station Config page to verify the key exists on the target station before running a test. If the key is missing the template resolves to an empty string with no obvious error at runtime.

Example using AGENT_HOST (the scaffold default):

Key Example value Scope
AGENT_HOST http://agent64.local:5000 ST-01
AGENT_HOST http://agent72.local:5000 ST-02

Example using a site-specific key name Accordion:

Key Example value Scope
Accordion http://agent64.local:5000 ST-01

In both cases update the YAML to match:

parameters:
  host: "{{cfg.AGENT_HOST}}"   # or  "{{cfg.Accordion}}" — must match exactly

Verifying config via MCP tools

Before running a test that uses {{cfg.KEY_NAME}}, confirm the key is set:

# List all config keys for a station
list_config_keys(scope="ST-01")

# Or read the merged (global + station) config in one call
get_merged_config(stationId="ST-01")

# Set a missing key
set_config_value(key="AGENT_HOST", value="http://agent64.local:5000",
                 scope="ST-01", category="Instruments")

Adding the NuGet package (.NET)

Add AccordionQ2.WebApiClient to the runner project (not the MSTest project):

<PackageReference Include="AccordionQ2.WebApiClient" Version="5.2.0" />

Verify the current version at the NuGet package page before adding the reference.

Adding the pip package (Python)

Declare accordionq2 in package.json:

{
  "requirements": {
    "pipPackages": ["accordionq2"]
  }
}

For air-gapped production stations, vendor the wheel — see sdk/python-dependencies.md.

An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.