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:
- A
Connectmethod/function is wired as a YAMLsetup:step withpost_execution_action: terminate-on-fail. It receives the instrument host address from{{cfg.AGENT_HOST}}— never hard-coded. - A
Disconnectmethod/function is wired as a YAMLteardown:step withrun_on_abort: true, guaranteeing cleanup even on abort. - The host address IS stored in Station Config under the key
AGENT_HOSTand 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.