testerkit 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- testerkit/__init__.py +68 -0
- testerkit/_docs/_assets/operator-ui/channels/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/dashboard/runs.png +0 -0
- testerkit/_docs/_assets/operator-ui/dashboard/stations.png +0 -0
- testerkit/_docs/_assets/operator-ui/events/filters.png +0 -0
- testerkit/_docs/_assets/operator-ui/events/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/explore/chart.png +0 -0
- testerkit/_docs/_assets/operator-ui/explore/filters.png +0 -0
- testerkit/_docs/_assets/operator-ui/explore/plot-controls.png +0 -0
- testerkit/_docs/_assets/operator-ui/files/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/launch/form.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/filters.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/pareto.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/ppk.png +0 -0
- testerkit/_docs/_assets/operator-ui/metrics/yield.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-header.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-measurements.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-overview.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/detail-steps.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/stats.png +0 -0
- testerkit/_docs/_assets/operator-ui/results/table.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/designer.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/docs.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/fixtures.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/instruments.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/parts.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/profiles.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/stations.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/tests.png +0 -0
- testerkit/_docs/_assets/operator-ui/tour/uuts.png +0 -0
- testerkit/_docs/concepts/configuration/capabilities.md +447 -0
- testerkit/_docs/concepts/configuration/fixtures.md +335 -0
- testerkit/_docs/concepts/configuration/index.md +14 -0
- testerkit/_docs/concepts/configuration/parts.md +276 -0
- testerkit/_docs/concepts/configuration/stations.md +214 -0
- testerkit/_docs/concepts/data/data-stores.md +199 -0
- testerkit/_docs/concepts/data/event-log.md +185 -0
- testerkit/_docs/concepts/data/event-sourcing.md +76 -0
- testerkit/_docs/concepts/data/flight-streaming.md +58 -0
- testerkit/_docs/concepts/data/index.md +17 -0
- testerkit/_docs/concepts/data/sessions.md +78 -0
- testerkit/_docs/concepts/data/three-verbs.md +260 -0
- testerkit/_docs/concepts/execution/index.md +13 -0
- testerkit/_docs/concepts/execution/outcomes.md +199 -0
- testerkit/_docs/concepts/execution/step-hierarchy.md +170 -0
- testerkit/_docs/concepts/execution/step-manifest.md +115 -0
- testerkit/_docs/concepts/index.md +40 -0
- testerkit/_docs/concepts/overview/ai-integration.md +57 -0
- testerkit/_docs/concepts/overview/architecture.md +357 -0
- testerkit/_docs/concepts/overview/index.md +14 -0
- testerkit/_docs/concepts/overview/platform-vs-framework.md +147 -0
- testerkit/_docs/concepts/overview/pytest.md +53 -0
- testerkit/_docs/concepts/overview/tiers.md +46 -0
- testerkit/_docs/how-to/catalog/datasheet-to-test.md +169 -0
- testerkit/_docs/how-to/catalog/index.md +11 -0
- testerkit/_docs/how-to/configuration/configuring-stations.md +364 -0
- testerkit/_docs/how-to/configuration/custom-drivers.md +484 -0
- testerkit/_docs/how-to/configuration/index.md +13 -0
- testerkit/_docs/how-to/configuration/mock-mode.md +342 -0
- testerkit/_docs/how-to/data/benchmarking.md +120 -0
- testerkit/_docs/how-to/data/capture-an-artifact.md +84 -0
- testerkit/_docs/how-to/data/capture-waveform.md +110 -0
- testerkit/_docs/how-to/data/choosing-a-channel-verb.md +108 -0
- testerkit/_docs/how-to/data/compare-runs.md +120 -0
- testerkit/_docs/how-to/data/export-results.md +104 -0
- testerkit/_docs/how-to/data/find-flaky-tests.md +108 -0
- testerkit/_docs/how-to/data/grafana-dashboards.md +148 -0
- testerkit/_docs/how-to/data/index.md +23 -0
- testerkit/_docs/how-to/data/mcp-debug-failures.md +125 -0
- testerkit/_docs/how-to/data/mcp-query-runs.md +120 -0
- testerkit/_docs/how-to/data/querying-channels.md +117 -0
- testerkit/_docs/how-to/data/querying-events.md +85 -0
- testerkit/_docs/how-to/data/stream-live-channel.md +134 -0
- testerkit/_docs/how-to/execution/custom-operator-ui.md +136 -0
- testerkit/_docs/how-to/execution/index.md +21 -0
- testerkit/_docs/how-to/execution/limits.md +193 -0
- testerkit/_docs/how-to/execution/managing-sessions.md +100 -0
- testerkit/_docs/how-to/execution/multi-uut-testing.md +211 -0
- testerkit/_docs/how-to/execution/operator-prompts.md +151 -0
- testerkit/_docs/how-to/execution/profiles.md +304 -0
- testerkit/_docs/how-to/execution/spec-driven-testing.md +169 -0
- testerkit/_docs/how-to/execution/test-context.md +212 -0
- testerkit/_docs/how-to/execution/traceability.md +252 -0
- testerkit/_docs/how-to/execution/vector-expansion.md +394 -0
- testerkit/_docs/how-to/execution/writing-tests.md +363 -0
- testerkit/_docs/how-to/index.md +59 -0
- testerkit/_docs/how-to/overview/index.md +11 -0
- testerkit/_docs/how-to/overview/mcp-integration.md +168 -0
- testerkit/_docs/how-to/overview/operator-ui-tour.md +234 -0
- testerkit/_docs/integration/data/grafana.md +162 -0
- testerkit/_docs/integration/data/index.md +15 -0
- testerkit/_docs/integration/data/lakehouse-import.md +226 -0
- testerkit/_docs/integration/data/logging.md +131 -0
- testerkit/_docs/integration/data/results-api.md +51 -0
- testerkit/_docs/integration/index.md +20 -0
- testerkit/_docs/integration/runtime/harness.md +281 -0
- testerkit/_docs/integration/runtime/index.md +13 -0
- testerkit/_docs/integration/runtime/instruments.md +284 -0
- testerkit/_docs/integration/runtime/pytest-existing.md +315 -0
- testerkit/_docs/reference/catalog/cookbook.md +389 -0
- testerkit/_docs/reference/catalog/index.md +11 -0
- testerkit/_docs/reference/catalog/schema.md +375 -0
- testerkit/_docs/reference/cli.md +660 -0
- testerkit/_docs/reference/configuration.md +406 -0
- testerkit/_docs/reference/data/channels-schema.md +145 -0
- testerkit/_docs/reference/data/event-types.md +554 -0
- testerkit/_docs/reference/data/events-schema.md +120 -0
- testerkit/_docs/reference/data/files-schema.md +141 -0
- testerkit/_docs/reference/data/index.md +18 -0
- testerkit/_docs/reference/data/models.md +2229 -0
- testerkit/_docs/reference/data/outputs.md +82 -0
- testerkit/_docs/reference/data/parquet-schema.md +529 -0
- testerkit/_docs/reference/data/performance-limits.md +224 -0
- testerkit/_docs/reference/data/query-api.md +247 -0
- testerkit/_docs/reference/index.md +69 -0
- testerkit/_docs/reference/operator-ui/channels/detail.md +82 -0
- testerkit/_docs/reference/operator-ui/channels/list.md +70 -0
- testerkit/_docs/reference/operator-ui/dashboard.md +87 -0
- testerkit/_docs/reference/operator-ui/designer.md +167 -0
- testerkit/_docs/reference/operator-ui/events.md +89 -0
- testerkit/_docs/reference/operator-ui/files.md +74 -0
- testerkit/_docs/reference/operator-ui/fixtures.md +100 -0
- testerkit/_docs/reference/operator-ui/instruments.md +126 -0
- testerkit/_docs/reference/operator-ui/launch.md +79 -0
- testerkit/_docs/reference/operator-ui/live.md +102 -0
- testerkit/_docs/reference/operator-ui/measurements.md +159 -0
- testerkit/_docs/reference/operator-ui/metrics.md +217 -0
- testerkit/_docs/reference/operator-ui/parts.md +98 -0
- testerkit/_docs/reference/operator-ui/profiles.md +103 -0
- testerkit/_docs/reference/operator-ui/results/detail.md +214 -0
- testerkit/_docs/reference/operator-ui/results/list.md +106 -0
- testerkit/_docs/reference/operator-ui/stations.md +98 -0
- testerkit/_docs/reference/operator-ui/tests.md +173 -0
- testerkit/_docs/reference/operator-ui/uuts.md +67 -0
- testerkit/_docs/reference/overview/index.md +11 -0
- testerkit/_docs/reference/overview/pytest-native.md +142 -0
- testerkit/_docs/reference/overview/skills.md +177 -0
- testerkit/_docs/reference/pytest/fixtures.md +342 -0
- testerkit/_docs/reference/pytest/index.md +12 -0
- testerkit/_docs/reference/pytest/markers.md +257 -0
- testerkit/_docs/reference/runtime/api.md +246 -0
- testerkit/_docs/reference/runtime/client.md +280 -0
- testerkit/_docs/reference/runtime/connect.md +140 -0
- testerkit/_docs/reference/runtime/index.md +13 -0
- testerkit/_docs/tutorial/01-first-test.md +113 -0
- testerkit/_docs/tutorial/02-mock-instruments.md +88 -0
- testerkit/_docs/tutorial/03-fixtures.md +169 -0
- testerkit/_docs/tutorial/04-limits.md +139 -0
- testerkit/_docs/tutorial/05-configuration.md +194 -0
- testerkit/_docs/tutorial/06-specifications.md +273 -0
- testerkit/_docs/tutorial/07-real-instruments.md +245 -0
- testerkit/_docs/tutorial/08-capabilities.md +223 -0
- testerkit/_docs/tutorial/09-production.md +374 -0
- testerkit/_docs/tutorial/10-live-monitoring.md +156 -0
- testerkit/_docs/tutorial/11-waveforms-and-evidence.md +169 -0
- testerkit/_docs/tutorial/12-continuous-monitoring.md +145 -0
- testerkit/_docs/tutorial/13-parallel-testing.md +233 -0
- testerkit/_docs/tutorial/index.md +61 -0
- testerkit/_docs/tutorial/quickstart.md +282 -0
- testerkit/analysis/__init__.py +9 -0
- testerkit/analysis/_common.py +24 -0
- testerkit/analysis/measurement_facets.py +524 -0
- testerkit/analysis/measurements_query.py +1458 -0
- testerkit/analysis/metrics.py +389 -0
- testerkit/analysis/runs_query.py +434 -0
- testerkit/analysis/steps_query.py +413 -0
- testerkit/api/__init__.py +6 -0
- testerkit/api/_mime.py +71 -0
- testerkit/api/app.py +1171 -0
- testerkit/api/dialogs/__init__.py +36 -0
- testerkit/api/dialogs/manager.py +617 -0
- testerkit/api/dialogs/models.py +79 -0
- testerkit/api/models.py +80 -0
- testerkit/api/responses.py +205 -0
- testerkit/api/runner.py +222 -0
- testerkit/api/schemas.py +311 -0
- testerkit/benchmark/__init__.py +34 -0
- testerkit/benchmark/concurrency.py +248 -0
- testerkit/benchmark/core.py +232 -0
- testerkit/benchmark/runner.py +628 -0
- testerkit/benchmark/scenario.py +313 -0
- testerkit/benchmark/system.py +191 -0
- testerkit/benchmark/workloads.py +507 -0
- testerkit/catalog/__init__.py +6 -0
- testerkit/catalog/generic/generic_dmm.yaml +61 -0
- testerkit/catalog/generic/generic_eload.yaml +31 -0
- testerkit/catalog/generic/generic_fgen.yaml +56 -0
- testerkit/catalog/generic/generic_oscilloscope.yaml +45 -0
- testerkit/catalog/generic/generic_psu.yaml +77 -0
- testerkit/catalog/generic/generic_smu.yaml +73 -0
- testerkit/channels.py +538 -0
- testerkit/cli/__init__.py +32 -0
- testerkit/cli/_common.py +113 -0
- testerkit/cli/_time.py +179 -0
- testerkit/cli/benchmark_cmd.py +56 -0
- testerkit/cli/catalog_cmd.py +39 -0
- testerkit/cli/daemon.py +157 -0
- testerkit/cli/data_cmd.py +1040 -0
- testerkit/cli/discover_cmd.py +94 -0
- testerkit/cli/docs_cmd.py +100 -0
- testerkit/cli/instrument.py +172 -0
- testerkit/cli/mcp_cmd.py +37 -0
- testerkit/cli/metrics.py +366 -0
- testerkit/cli/project.py +312 -0
- testerkit/cli/root.py +14 -0
- testerkit/cli/runs.py +412 -0
- testerkit/cli/schema_cmd.py +87 -0
- testerkit/cli/serve_cmd.py +50 -0
- testerkit/cli/setup_cmd.py +604 -0
- testerkit/cli/station.py +294 -0
- testerkit/cli/validate.py +112 -0
- testerkit/client.py +463 -0
- testerkit/connect.py +635 -0
- testerkit/data/__init__.py +8 -0
- testerkit/data/_accumulator_pool.py +455 -0
- testerkit/data/_atomic.py +59 -0
- testerkit/data/_collection_indices.py +67 -0
- testerkit/data/_daemon_lifecycle.py +535 -0
- testerkit/data/_duckdb_daemon.py +695 -0
- testerkit/data/_duckdb_flight_server.py +813 -0
- testerkit/data/_event_filters.py +15 -0
- testerkit/data/_event_reader.py +101 -0
- testerkit/data/_flight_errors.py +199 -0
- testerkit/data/_flight_query.py +202 -0
- testerkit/data/_flight_retry.py +148 -0
- testerkit/data/_flight_subscribe.py +67 -0
- testerkit/data/_index_epoch.py +342 -0
- testerkit/data/_ipc_writer.py +185 -0
- testerkit/data/_json_safe.py +63 -0
- testerkit/data/_process.py +18 -0
- testerkit/data/_push_relay.py +124 -0
- testerkit/data/_runs_duckdb_daemon.py +2704 -0
- testerkit/data/_session_reaper.py +110 -0
- testerkit/data/_sql_helpers.py +30 -0
- testerkit/data/_store.py +24 -0
- testerkit/data/backends/__init__.py +7 -0
- testerkit/data/backends/_event_accumulator.py +957 -0
- testerkit/data/backends/_row_helpers.py +1172 -0
- testerkit/data/backends/parquet.py +1143 -0
- testerkit/data/backends/protocol.py +35 -0
- testerkit/data/channels/__init__.py +8 -0
- testerkit/data/channels/_flight_daemon.py +75 -0
- testerkit/data/channels/client.py +242 -0
- testerkit/data/channels/flight_manager.py +88 -0
- testerkit/data/channels/index.py +664 -0
- testerkit/data/channels/models.py +418 -0
- testerkit/data/channels/server.py +162 -0
- testerkit/data/channels/store.py +1481 -0
- testerkit/data/data_dir.py +61 -0
- testerkit/data/duckdb_manager.py +79 -0
- testerkit/data/event_log.py +384 -0
- testerkit/data/event_store.py +768 -0
- testerkit/data/events.py +1025 -0
- testerkit/data/exporters/__init__.py +6 -0
- testerkit/data/exporters/_helpers.py +40 -0
- testerkit/data/exporters/csv_exporter.py +168 -0
- testerkit/data/exporters/hdf5.py +234 -0
- testerkit/data/exporters/json_exporter.py +229 -0
- testerkit/data/exporters/mdf4.py +201 -0
- testerkit/data/exporters/stdf.py +255 -0
- testerkit/data/exporters/tdms.py +292 -0
- testerkit/data/files/__init__.py +71 -0
- testerkit/data/files/_backend.py +207 -0
- testerkit/data/files/_catalog_daemon.py +84 -0
- testerkit/data/files/catalog.py +218 -0
- testerkit/data/files/catalog_manager.py +325 -0
- testerkit/data/files/models.py +60 -0
- testerkit/data/files/serializers.py +414 -0
- testerkit/data/files/store.py +463 -0
- testerkit/data/files/streaming.py +783 -0
- testerkit/data/models.py +604 -0
- testerkit/data/ref.py +152 -0
- testerkit/data/retention.py +297 -0
- testerkit/data/run_store.py +367 -0
- testerkit/data/runs_duckdb_manager.py +103 -0
- testerkit/data/schema_dispatch.py +191 -0
- testerkit/data/schema_migrate.py +76 -0
- testerkit/data/schema_versions.py +85 -0
- testerkit/data/schemas.py +288 -0
- testerkit/data/subscribers/__init__.py +48 -0
- testerkit/data/subscribers/_base.py +20 -0
- testerkit/data/subscribers/_output_file.py +25 -0
- testerkit/data/subscribers/replay.py +55 -0
- testerkit/environment.py +84 -0
- testerkit/execution/__init__.py +11 -0
- testerkit/execution/_git.py +190 -0
- testerkit/execution/_state.py +740 -0
- testerkit/execution/accessors.py +54 -0
- testerkit/execution/audit.py +51 -0
- testerkit/execution/cascade.py +85 -0
- testerkit/execution/connections.py +491 -0
- testerkit/execution/harness.py +1931 -0
- testerkit/execution/instrument_events.py +42 -0
- testerkit/execution/limits.py +154 -0
- testerkit/execution/metadata.py +102 -0
- testerkit/execution/mocks.py +63 -0
- testerkit/execution/profiles.py +616 -0
- testerkit/execution/run_scope.py +1331 -0
- testerkit/execution/session_scope.py +196 -0
- testerkit/execution/sidecar.py +280 -0
- testerkit/execution/site_runner.py +705 -0
- testerkit/execution/sites.py +183 -0
- testerkit/execution/sync.py +294 -0
- testerkit/execution/uut_provider.py +231 -0
- testerkit/execution/vectors.py +205 -0
- testerkit/execution/verify.py +396 -0
- testerkit/expand.py +75 -0
- testerkit/files.py +235 -0
- testerkit/fixtures/__init__.py +6 -0
- testerkit/fixtures/manager.py +357 -0
- testerkit/grafana/__init__.py +1 -0
- testerkit/grafana/bootstrap.py +61 -0
- testerkit/grafana/cli.py +314 -0
- testerkit/grafana/dashboards/asset_utilization.json +92 -0
- testerkit/grafana/dashboards/channel_explorer.json +77 -0
- testerkit/grafana/dashboards/event_log.json +92 -0
- testerkit/grafana/dashboards/failure_pareto.json +104 -0
- testerkit/grafana/dashboards/measurement_distribution.json +97 -0
- testerkit/grafana/dashboards/measurement_trend.json +161 -0
- testerkit/grafana/dashboards/station_comparison.json +95 -0
- testerkit/grafana/dashboards/test_duration.json +104 -0
- testerkit/grafana/dashboards/unit_traceability.json +73 -0
- testerkit/grafana/dashboards/yield_overview.json +189 -0
- testerkit/grafana/provisioning/dashboards.yaml.j2 +12 -0
- testerkit/grafana/provisioning/datasources.yaml.j2 +17 -0
- testerkit/grafana/server.py +282 -0
- testerkit/init.py +724 -0
- testerkit/instruments/__init__.py +10 -0
- testerkit/instruments/base.py +82 -0
- testerkit/instruments/discovery/__init__.py +62 -0
- testerkit/instruments/discovery/_base.py +174 -0
- testerkit/instruments/discovery/lxi.py +152 -0
- testerkit/instruments/discovery/ni.py +95 -0
- testerkit/instruments/discovery/serial.py +73 -0
- testerkit/instruments/discovery/visa.py +98 -0
- testerkit/instruments/lifecycle.py +213 -0
- testerkit/instruments/loader.py +79 -0
- testerkit/instruments/locks.py +178 -0
- testerkit/instruments/mocks.py +230 -0
- testerkit/instruments/observer.py +270 -0
- testerkit/instruments/observers/__init__.py +36 -0
- testerkit/instruments/observers/_base.py +68 -0
- testerkit/instruments/observers/daqmx.py +70 -0
- testerkit/instruments/observers/descriptor.py +69 -0
- testerkit/instruments/observers/generic.py +92 -0
- testerkit/instruments/observers/lantz.py +31 -0
- testerkit/instruments/observers/modbus.py +96 -0
- testerkit/instruments/observers/motion.py +68 -0
- testerkit/instruments/observers/ni_modular.py +73 -0
- testerkit/instruments/observers/ophyd.py +80 -0
- testerkit/instruments/observers/pymeasure.py +120 -0
- testerkit/instruments/observers/qcodes.py +66 -0
- testerkit/instruments/observers/scpi.py +88 -0
- testerkit/instruments/observers/tektronix.py +57 -0
- testerkit/instruments/observers/visa.py +103 -0
- testerkit/instruments/pool.py +459 -0
- testerkit/instruments/proxy.py +59 -0
- testerkit/instruments/route_manager.py +329 -0
- testerkit/instruments/routed_proxy.py +88 -0
- testerkit/instruments/server.py +508 -0
- testerkit/instruments/switch.py +43 -0
- testerkit/instruments/visa.py +294 -0
- testerkit/matching/__init__.py +6 -0
- testerkit/matching/service.py +969 -0
- testerkit/mcp/__init__.py +6 -0
- testerkit/mcp/server.py +681 -0
- testerkit/mcp/tools.py +1868 -0
- testerkit/models/__init__.py +18 -0
- testerkit/models/capability.py +598 -0
- testerkit/models/catalog.py +76 -0
- testerkit/models/data_options.py +153 -0
- testerkit/models/enums.py +334 -0
- testerkit/models/instrument.py +152 -0
- testerkit/models/instrument_asset.py +25 -0
- testerkit/models/part.py +271 -0
- testerkit/models/part_manifest.py +96 -0
- testerkit/models/project.py +114 -0
- testerkit/models/station.py +140 -0
- testerkit/models/test_config.py +748 -0
- testerkit/ontology/__init__.py +39 -0
- testerkit/ontology/schema.py +188 -0
- testerkit/ontology/testerkit.yaml +1420 -0
- testerkit/parts/__init__.py +8 -0
- testerkit/parts/context.py +181 -0
- testerkit/parts/folder.py +251 -0
- testerkit/parts/loader.py +27 -0
- testerkit/prompts/__init__.py +17 -0
- testerkit/prompts/core.py +133 -0
- testerkit/pytest_plugin/__init__.py +1287 -0
- testerkit/pytest_plugin/autouse.py +369 -0
- testerkit/pytest_plugin/helpers.py +354 -0
- testerkit/pytest_plugin/hooks.py +1982 -0
- testerkit/pytest_plugin/markers.py +203 -0
- testerkit/pytest_plugin/retry.py +37 -0
- testerkit/pytest_plugin/sweeps.py +117 -0
- testerkit/queries.py +78 -0
- testerkit/reports/__init__.py +6 -0
- testerkit/reports/core.py +492 -0
- testerkit/reports/datasheet.py +831 -0
- testerkit/reports/templates/datasheet.html +383 -0
- testerkit/reports/templates/default.html +153 -0
- testerkit/sbom.py +142 -0
- testerkit/schema_export.py +101 -0
- testerkit/signals.py +63 -0
- testerkit/skills/README.md +58 -0
- testerkit/skills/templates/project-instructions.md +125 -0
- testerkit/skills/testerkit-analysis/SKILL.md +87 -0
- testerkit/skills/testerkit-capture/SKILL.md +114 -0
- testerkit/skills/testerkit-data/SKILL.md +138 -0
- testerkit/skills/testerkit-datasheets/SKILL.md +100 -0
- testerkit/skills/testerkit-datasheets/agents/scaffold-writer.md +115 -0
- testerkit/skills/testerkit-datasheets/agents/section-extractor.md +98 -0
- testerkit/skills/testerkit-datasheets/agents/section-reviewer.md +153 -0
- testerkit/skills/testerkit-datasheets/agents/section-splitter.md +89 -0
- testerkit/skills/testerkit-datasheets/agents/section-writer.md +226 -0
- testerkit/skills/testerkit-datasheets/references/catalog-pipeline.md +271 -0
- testerkit/skills/testerkit-datasheets/references/process-queue.md +42 -0
- testerkit/skills/testerkit-datasheets/references/scaffold.md +156 -0
- testerkit/skills/testerkit-datasheets/references/test-pipeline.md +312 -0
- testerkit/skills/testerkit-debug/SKILL.md +127 -0
- testerkit/skills/testerkit-interactive/SKILL.md +188 -0
- testerkit/skills/testerkit-interactive/references/live-ui-patterns.md +102 -0
- testerkit/skills/testerkit-mocks/SKILL.md +128 -0
- testerkit/skills/testerkit-parts/SKILL.md +126 -0
- testerkit/skills/testerkit-profiles/SKILL.md +139 -0
- testerkit/skills/testerkit-sites/SKILL.md +140 -0
- testerkit/skills/testerkit-stations/SKILL.md +146 -0
- testerkit/skills/testerkit-tests/SKILL.md +136 -0
- testerkit/store.py +1639 -0
- testerkit/ui/__init__.py +71 -0
- testerkit/ui/_asgi.py +162 -0
- testerkit/ui/app.py +32 -0
- testerkit/ui/components/__init__.py +13 -0
- testerkit/ui/components/artifact_viewer.py +250 -0
- testerkit/ui/components/channel_values.py +159 -0
- testerkit/ui/components/event_timeline.py +222 -0
- testerkit/ui/components/execution_gantt.py +210 -0
- testerkit/ui/components/file_streams.py +147 -0
- testerkit/ui/components/instrument_activity.py +146 -0
- testerkit/ui/components/session_table.py +118 -0
- testerkit/ui/pages/__init__.py +25 -0
- testerkit/ui/pages/channels/__init__.py +4 -0
- testerkit/ui/pages/channels/detail.py +932 -0
- testerkit/ui/pages/channels/list.py +515 -0
- testerkit/ui/pages/dashboard.py +236 -0
- testerkit/ui/pages/designer/__init__.py +5 -0
- testerkit/ui/pages/designer/graph.py +635 -0
- testerkit/ui/pages/designer/matching.py +663 -0
- testerkit/ui/pages/designer/page.py +593 -0
- testerkit/ui/pages/designer/properties.py +591 -0
- testerkit/ui/pages/designer/state.py +468 -0
- testerkit/ui/pages/docs/__init__.py +6 -0
- testerkit/ui/pages/docs/index.py +95 -0
- testerkit/ui/pages/docs/page.py +698 -0
- testerkit/ui/pages/events/__init__.py +3 -0
- testerkit/ui/pages/events/list.py +263 -0
- testerkit/ui/pages/explore.py +1108 -0
- testerkit/ui/pages/files/__init__.py +4 -0
- testerkit/ui/pages/files/detail.py +426 -0
- testerkit/ui/pages/files/list.py +447 -0
- testerkit/ui/pages/fixtures/__init__.py +8 -0
- testerkit/ui/pages/fixtures/detail.py +280 -0
- testerkit/ui/pages/fixtures/edit.py +370 -0
- testerkit/ui/pages/fixtures/list.py +180 -0
- testerkit/ui/pages/fixtures/new.py +195 -0
- testerkit/ui/pages/instruments/__init__.py +4 -0
- testerkit/ui/pages/instruments/detail.py +320 -0
- testerkit/ui/pages/instruments/edit.py +482 -0
- testerkit/ui/pages/instruments/list.py +249 -0
- testerkit/ui/pages/instruments/new.py +200 -0
- testerkit/ui/pages/launch.py +261 -0
- testerkit/ui/pages/live.py +124 -0
- testerkit/ui/pages/metrics_page.py +1229 -0
- testerkit/ui/pages/parts/__init__.py +11 -0
- testerkit/ui/pages/parts/detail.py +202 -0
- testerkit/ui/pages/parts/edit.py +310 -0
- testerkit/ui/pages/parts/list.py +160 -0
- testerkit/ui/pages/parts/new.py +170 -0
- testerkit/ui/pages/parts/requirements.py +153 -0
- testerkit/ui/pages/parts/stations.py +199 -0
- testerkit/ui/pages/profiles/__init__.py +4 -0
- testerkit/ui/pages/profiles/detail.py +113 -0
- testerkit/ui/pages/profiles/list.py +86 -0
- testerkit/ui/pages/results/__init__.py +4 -0
- testerkit/ui/pages/results/detail.py +631 -0
- testerkit/ui/pages/results/list.py +230 -0
- testerkit/ui/pages/stations/__init__.py +4 -0
- testerkit/ui/pages/stations/detail.py +256 -0
- testerkit/ui/pages/stations/edit.py +273 -0
- testerkit/ui/pages/stations/list.py +180 -0
- testerkit/ui/pages/stations/new.py +311 -0
- testerkit/ui/pages/tests/__init__.py +4 -0
- testerkit/ui/pages/tests/detail.py +152 -0
- testerkit/ui/pages/tests/list.py +194 -0
- testerkit/ui/pages/uuts/__init__.py +4 -0
- testerkit/ui/pages/uuts/list.py +97 -0
- testerkit/ui/shared/__init__.py +8 -0
- testerkit/ui/shared/components.py +1826 -0
- testerkit/ui/shared/dialogs.py +105 -0
- testerkit/ui/shared/event_binding.py +194 -0
- testerkit/ui/shared/layout.py +314 -0
- testerkit/ui/shared/services.py +1719 -0
- testerkit/ui/shared/timestamps.py +21 -0
- testerkit/ui/static/branding/favicon-16.png +0 -0
- testerkit/ui/static/branding/favicon-32.png +0 -0
- testerkit/ui/static/branding/favicon-48.png +0 -0
- testerkit/ui/static/branding/testerkit-icon-256.png +0 -0
- testerkit/ui/static/branding/testerkit-mark.svg +1 -0
- testerkit/ui/static/branding/testerkit-wordmark.svg +1 -0
- testerkit/ui/static/global.css +465 -0
- testerkit/utils/__init__.py +17 -0
- testerkit/utils/enum_meta.py +800 -0
- testerkit/utils/paths.py +75 -0
- testerkit/utils/ranges.py +257 -0
- testerkit/validation.py +82 -0
- testerkit/verbs.py +142 -0
- testerkit-0.4.0.dist-info/METADATA +250 -0
- testerkit-0.4.0.dist-info/RECORD +521 -0
- testerkit-0.4.0.dist-info/WHEEL +4 -0
- testerkit-0.4.0.dist-info/entry_points.txt +5 -0
- testerkit-0.4.0.dist-info/licenses/LICENSE +191 -0
testerkit/__init__.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""TesterKit - Hardware test platform for the AI-assisted era.
|
|
2
|
+
|
|
3
|
+
User-facing surface. Everything in this module is part of the public
|
|
4
|
+
API contract that test writers, interactive users, custom UI builders,
|
|
5
|
+
and data-mover scripts should reach for.
|
|
6
|
+
|
|
7
|
+
Three import shapes — pick the shape that matches your use:
|
|
8
|
+
|
|
9
|
+
**Top-level names** — frequently-typed surfaces, available directly::
|
|
10
|
+
|
|
11
|
+
from testerkit import (
|
|
12
|
+
connect, verify, observe, stream,
|
|
13
|
+
Limit, Waveform, XYData, Outcome,
|
|
14
|
+
arange, linspace, logspace, geomspace, repeat,
|
|
15
|
+
Mock, TesterKitClient,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
**Grouped submodules** — related surfaces under a single namespace::
|
|
19
|
+
|
|
20
|
+
import testerkit.channels # channels.write, channels.stream
|
|
21
|
+
import testerkit.files # files.write, files.stream
|
|
22
|
+
import testerkit.queries # queries.RunsQuery, queries.MeasurementsQuery, ...
|
|
23
|
+
|
|
24
|
+
**Deep paths** — internals for TesterKit contributors only. If you find
|
|
25
|
+
yourself reaching for one of these in a test, example, doc, or
|
|
26
|
+
external script, file an issue — the user-facing surface is missing
|
|
27
|
+
a re-export.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
from importlib.metadata import PackageNotFoundError
|
|
31
|
+
from importlib.metadata import version as _pkg_version
|
|
32
|
+
|
|
33
|
+
from testerkit.client import TesterKitClient
|
|
34
|
+
from testerkit.connect import connect
|
|
35
|
+
from testerkit.data.models import Outcome, Waveform, XYData
|
|
36
|
+
from testerkit.expand import arange, geomspace, linspace, logspace, repeat
|
|
37
|
+
from testerkit.instruments.mocks import Mock
|
|
38
|
+
from testerkit.models.test_config import Limit
|
|
39
|
+
from testerkit.verbs import measure, observe, stream, verify
|
|
40
|
+
|
|
41
|
+
try:
|
|
42
|
+
# Single source of truth — read from the installed wheel's metadata
|
|
43
|
+
# so __version__ tracks pyproject.toml automatically. Editable
|
|
44
|
+
# installs (`uv pip install -e .`) populate metadata too.
|
|
45
|
+
__version__ = _pkg_version("testerkit")
|
|
46
|
+
except PackageNotFoundError:
|
|
47
|
+
# Imported from a source tree without `pip install`; safe fallback.
|
|
48
|
+
__version__ = "0.0.0+unknown"
|
|
49
|
+
|
|
50
|
+
__all__ = [
|
|
51
|
+
"__version__",
|
|
52
|
+
"Limit",
|
|
53
|
+
"TesterKitClient",
|
|
54
|
+
"Mock",
|
|
55
|
+
"Outcome",
|
|
56
|
+
"Waveform",
|
|
57
|
+
"XYData",
|
|
58
|
+
"arange",
|
|
59
|
+
"connect",
|
|
60
|
+
"geomspace",
|
|
61
|
+
"linspace",
|
|
62
|
+
"logspace",
|
|
63
|
+
"measure",
|
|
64
|
+
"observe",
|
|
65
|
+
"repeat",
|
|
66
|
+
"stream",
|
|
67
|
+
"verify",
|
|
68
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# Capabilities
|
|
2
|
+
|
|
3
|
+
**Capabilities** describe what instruments can do and what parts need. The capability system enables automatic matching between parts and stations using a signal-parameter model inspired by ATML (Automatic Test Markup Language) and IEEE 1641.
|
|
4
|
+
|
|
5
|
+
## The problem
|
|
6
|
+
|
|
7
|
+
A Keysight 34461A datasheet says it can measure "DC Voltage: 100 mV to 1000 V, 0.0035% + 0.0006% accuracy, 6.5-digit resolution." A part spec says "3.3 V output, ±5% tolerance." How do we connect these two worlds in a machine-readable way so the system can automatically determine whether a given instrument can test a given part?
|
|
8
|
+
|
|
9
|
+
We need a shared language that works for both sides. That language is `Capability`.
|
|
10
|
+
|
|
11
|
+
## What Is a Capability?
|
|
12
|
+
|
|
13
|
+
A capability has three core dimensions:
|
|
14
|
+
|
|
15
|
+
| Dimension | Examples | Description |
|
|
16
|
+
|-----------|---------|-------------|
|
|
17
|
+
| `function` | dc_voltage, ac_voltage, resistance, waveform, s_parameters, phase_noise, ... | Named measurement function |
|
|
18
|
+
| `direction` | input, output, bidir, transform | Does it measure, source, or transform? |
|
|
19
|
+
| `signals/conditions/controls/attributes` | voltage: {range: 0-1000V}, bandwidth: {value: 50MHz} | Named signal parameters organized by semantic role |
|
|
20
|
+
|
|
21
|
+
### Model Hierarchy
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Capability (base)
|
|
25
|
+
├── InstrumentCapability — adds channels, readback
|
|
26
|
+
└── PartCharacteristic — adds pin / pins / net / signal_group, datasheet_ref
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Every part characteristic must name at least one physical interface (`pin`, `pins`, `net`, or `signal_group`) — TesterKit won't load one without it.
|
|
30
|
+
|
|
31
|
+
Both share the same `function + direction + signals/conditions/controls/attributes` core. Direction always describes the hardware it's on: "input" means "this device receives/sinks signal."
|
|
32
|
+
|
|
33
|
+
### Example: DMM Capabilities
|
|
34
|
+
|
|
35
|
+
```yaml
|
|
36
|
+
# catalog/keysight_34461a.yaml or instruments/dmm.yaml
|
|
37
|
+
capabilities:
|
|
38
|
+
- function: dc_voltage
|
|
39
|
+
direction: input # Instrument measures (receives signal)
|
|
40
|
+
signals:
|
|
41
|
+
voltage:
|
|
42
|
+
range: {min: 0.0001, max: 1000, unit: V}
|
|
43
|
+
accuracy: {pct_reading: 0.0035, pct_range: 0.0006}
|
|
44
|
+
resolution: {digits: 6.5}
|
|
45
|
+
|
|
46
|
+
- function: dc_current
|
|
47
|
+
direction: input
|
|
48
|
+
signals:
|
|
49
|
+
current:
|
|
50
|
+
range: {min: 0.000001, max: 10, unit: A}
|
|
51
|
+
|
|
52
|
+
- function: resistance
|
|
53
|
+
direction: input
|
|
54
|
+
signals:
|
|
55
|
+
resistance:
|
|
56
|
+
range: {min: 0.01, max: 100000000, unit: Ohm}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Example: Power Supply Capabilities
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
# catalog/keysight_e36312a.yaml or instruments/psu.yaml
|
|
63
|
+
|
|
64
|
+
# Top-level structured channels describe physical topology
|
|
65
|
+
channels:
|
|
66
|
+
"1": {terminals: [hi, lo], connector: binding_post, ground: floating}
|
|
67
|
+
"2": {terminals: [hi, lo], connector: binding_post, ground: floating}
|
|
68
|
+
|
|
69
|
+
capabilities:
|
|
70
|
+
- function: dc_voltage
|
|
71
|
+
direction: output # Instrument sources (provides signal)
|
|
72
|
+
signals:
|
|
73
|
+
voltage:
|
|
74
|
+
range: {min: 0, max: 30, unit: V}
|
|
75
|
+
current:
|
|
76
|
+
range: {min: 0, max: 5, unit: A}
|
|
77
|
+
channels: ["1", "2"] # References to top-level channel keys
|
|
78
|
+
|
|
79
|
+
- function: dc_voltage
|
|
80
|
+
direction: input # Built-in readback meter
|
|
81
|
+
readback: true # Marks a built-in readback meter
|
|
82
|
+
signals:
|
|
83
|
+
voltage:
|
|
84
|
+
range: {min: 0, max: 30, unit: V}
|
|
85
|
+
channels: ["1", "2"]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Direction Pairing
|
|
89
|
+
|
|
90
|
+
The key insight is that **directions pair** between parts and instruments:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Part Characteristic Required Instrument Capability
|
|
94
|
+
───────────────────── ────────────────────────────────
|
|
95
|
+
output_voltage (OUTPUT) → dc_voltage (INPUT) — need to measure
|
|
96
|
+
input_voltage (INPUT) → dc_voltage (OUTPUT) — need to source
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Why This Works
|
|
100
|
+
|
|
101
|
+
When a part **outputs** voltage, the instrument needs to **input** (measure) that voltage.
|
|
102
|
+
|
|
103
|
+
When a part **inputs** power, the instrument needs to **output** (source) that power.
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
Part (UUT) Instrument
|
|
107
|
+
──────────── ──────────
|
|
108
|
+
|
|
109
|
+
output_voltage ────signal───► DMM (measures dc_voltage)
|
|
110
|
+
(OUTPUT) (INPUT)
|
|
111
|
+
|
|
112
|
+
◄───power──── PSU (sources dc_voltage)
|
|
113
|
+
input_voltage (OUTPUT)
|
|
114
|
+
(INPUT)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
You always write `direction` from the point of view of the hardware it sits on: `input` means that device receives signal, `output` means it sources signal — the same on a part or an instrument. The matcher pairs an OUTPUT on one side with an INPUT on the other.
|
|
118
|
+
|
|
119
|
+
## Capability Matching
|
|
120
|
+
|
|
121
|
+
The matcher determines whether a station can test a part by checking in tiers — you can stop at any tier, from function-only down through accuracy and resolution:
|
|
122
|
+
|
|
123
|
+
1. **Function match** — instrument has same `MeasurementFunction` as requirement
|
|
124
|
+
2. **Direction match** — directions pair correctly (part OUTPUT ↔ instrument INPUT, and vice versa). A `bidir` instrument satisfies any part direction; a `bidir` part needs a `bidir` instrument.
|
|
125
|
+
3. **Parameter range containment** — instrument's parameter ranges contain required values
|
|
126
|
+
4. **Accuracy** — instrument accuracy must be better than required (condition-aware via [`SpecBand`](../../reference/data/models.md), the value-plus-condition record)
|
|
127
|
+
5. **Resolution** — instrument resolution must meet or exceed required
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from testerkit.matching.service import find_compatible_stations
|
|
131
|
+
from testerkit.store import get_part
|
|
132
|
+
|
|
133
|
+
# Load by id (`get_part` looks up `parts/<id>.yaml` from the project root).
|
|
134
|
+
# Use `load_part(Path(...))` when you have an explicit path on disk.
|
|
135
|
+
part = get_part("power_board")
|
|
136
|
+
matches = find_compatible_stations(part) # takes the loaded Part object
|
|
137
|
+
|
|
138
|
+
for match in matches:
|
|
139
|
+
print(f"{match.station_id}: {'Compatible' if match.compatible else 'Missing capabilities'}")
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Matching Algorithm
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
# Part characteristic
|
|
146
|
+
char = part.characteristics["output_voltage"]
|
|
147
|
+
# function: dc_voltage, direction: OUTPUT
|
|
148
|
+
|
|
149
|
+
# Matching wraps characteristics into CapabilityRequirement
|
|
150
|
+
# Direction stays as-is (OUTPUT) — the matcher pairs the part's OUTPUT with the DMM's INPUT
|
|
151
|
+
|
|
152
|
+
# Station instrument provides:
|
|
153
|
+
# function: dc_voltage, direction: INPUT, signals: {voltage: {range: 0-1000V}}
|
|
154
|
+
# → Function match ✓, Direction pair (OUTPUT↔INPUT) ✓, Range contains 3.3V ✓
|
|
155
|
+
# → MATCH!
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## MeasurementFunction
|
|
159
|
+
|
|
160
|
+
The `MeasurementFunction` enum provides fine-grained signal identification, aligned with IVI (Interchangeable Virtual Instrument Foundation) instrument class specifications:
|
|
161
|
+
|
|
162
|
+
| Function | Description | Typical Instrument |
|
|
163
|
+
|----------|-------------|--------------------|
|
|
164
|
+
| **Basic Electrical** | | |
|
|
165
|
+
| `dc_voltage` | DC voltage measurement/sourcing | DMM, PSU |
|
|
166
|
+
| `ac_voltage` | AC voltage measurement | DMM |
|
|
167
|
+
| `dc_current` | DC current measurement/sourcing | DMM, PSU, SMU |
|
|
168
|
+
| `ac_current` | AC current measurement | DMM, clamp meter |
|
|
169
|
+
| `dc_power` | DC power measurement/calculation | SMU, derived |
|
|
170
|
+
| `ac_power` | AC power measurement | Power meter |
|
|
171
|
+
| `resistance` | 2-wire resistance | DMM |
|
|
172
|
+
| `resistance_4w` | 4-wire resistance | DMM |
|
|
173
|
+
| `capacitance` | Capacitance measurement | LCR meter, DMM |
|
|
174
|
+
| `inductance` | Inductance measurement | LCR meter |
|
|
175
|
+
| `impedance` | Impedance measurement | Impedance analyzer |
|
|
176
|
+
| **RLC Parameters** | | |
|
|
177
|
+
| `quality_factor` | Quality factor (Q) | LCR meter |
|
|
178
|
+
| `dissipation_factor` | Dissipation factor (D) | LCR meter |
|
|
179
|
+
| **Time/Frequency** | | |
|
|
180
|
+
| `frequency` | Frequency measurement | DMM, counter |
|
|
181
|
+
| `period` | Period measurement | Counter |
|
|
182
|
+
| `time_interval` | Time interval between events | Counter |
|
|
183
|
+
| `pulse_width` | Pulse width measurement | Counter, scope |
|
|
184
|
+
| `duty_cycle` | Duty cycle measurement | Counter, scope |
|
|
185
|
+
| `phase` | Phase measurement | Counter, scope |
|
|
186
|
+
| **Waveform** | | |
|
|
187
|
+
| `waveform` | Time-domain waveform capture/generation | Oscilloscope, FGen |
|
|
188
|
+
| **Edge Timing** | | |
|
|
189
|
+
| `rise_time` | Rise time measurement | Oscilloscope |
|
|
190
|
+
| `fall_time` | Fall time measurement | Oscilloscope |
|
|
191
|
+
| **RF Measurements** | | |
|
|
192
|
+
| `rf_power` | RF power measurement | Power meter |
|
|
193
|
+
| `rf_cw` | CW signal generation | RF signal generator |
|
|
194
|
+
| `s_parameters` | S-parameter measurement | VNA |
|
|
195
|
+
| `spectrum` | Frequency-domain analysis | Spectrum analyzer |
|
|
196
|
+
| `phase_noise` | Phase noise measurement | Signal/spectrum analyzer |
|
|
197
|
+
| `noise_figure` | Noise figure measurement | NF analyzer |
|
|
198
|
+
| `harmonics` | Harmonic distortion | Spectrum analyzer |
|
|
199
|
+
| **Digital/Logic** | | |
|
|
200
|
+
| `digital_pattern` | Digital pattern generation/capture | Logic analyzer, pattern gen |
|
|
201
|
+
| `digital_io` | Digital I/O, GPIO | Digital I/O card |
|
|
202
|
+
| `serial_data` | Serial protocol decode | Logic analyzer |
|
|
203
|
+
| **Signal Integrity** | | |
|
|
204
|
+
| `jitter` | Jitter measurement | Oscilloscope, TIA |
|
|
205
|
+
| `eye_diagram` | Eye diagram analysis | Oscilloscope |
|
|
206
|
+
| `power_quality` | Power quality analysis | Power analyzer |
|
|
207
|
+
| **Miscellaneous** | | |
|
|
208
|
+
| `temperature` | Temperature measurement | DMM (RTD/TC), chamber |
|
|
209
|
+
| `diode` | Diode test | DMM |
|
|
210
|
+
| `continuity` | Continuity test | DMM |
|
|
211
|
+
| `optical_power` | Optical power measurement | Optical power meter |
|
|
212
|
+
| `wavelength` | Wavelength measurement | Optical spectrum analyzer |
|
|
213
|
+
| `magnetic_field` | Magnetic field measurement | Gaussmeter |
|
|
214
|
+
| `position` | Position/displacement | Encoder, stage controller |
|
|
215
|
+
|
|
216
|
+
The `transform` direction is used for signal-path components (amplifiers, filters, mixers) that modify signals rather than measuring or sourcing them.
|
|
217
|
+
|
|
218
|
+
Each function names one measurement precisely — a DMM measuring `dc_voltage` and a scope capturing `waveform` are separate functions.
|
|
219
|
+
|
|
220
|
+
### Waveform Shapes
|
|
221
|
+
|
|
222
|
+
For function generators and waveform sources, the `MeasurementFunction.WAVEFORM` is used with a `WaveformShape` parameter to specify supported shapes:
|
|
223
|
+
|
|
224
|
+
```yaml
|
|
225
|
+
# Function generator waveform shapes
|
|
226
|
+
- sine
|
|
227
|
+
- square
|
|
228
|
+
- triangle
|
|
229
|
+
- ramp
|
|
230
|
+
- pulse
|
|
231
|
+
- arbitrary
|
|
232
|
+
- noise
|
|
233
|
+
- dc
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Per IEEE 1641 (the test-vocabulary standard underlying ATML), waveform shapes are **characteristics of the signal**, not distinct signal types. Function generators should have a single `function: waveform` capability rather than separate capabilities for each shape.
|
|
237
|
+
|
|
238
|
+
## Typed Collections
|
|
239
|
+
|
|
240
|
+
Each capability organizes parameters into four semantic categories:
|
|
241
|
+
|
|
242
|
+
| Collection | Purpose | Examples |
|
|
243
|
+
|-----------|---------|----------|
|
|
244
|
+
| `signals` | What's being measured/sourced | voltage, current, resistance — has range, accuracy, resolution |
|
|
245
|
+
| `conditions` | Operating conditions affecting accuracy | frequency, temperature, load — range only, used for SpecBand matching |
|
|
246
|
+
| `controls` | User knobs that can be configured | attenuation, filter_type, range_select — range or options |
|
|
247
|
+
| `attributes` | Fixed facts about the capability | bandwidth, max_frequency — fixed value, no comparison needed |
|
|
248
|
+
|
|
249
|
+
### Why four separate collections?
|
|
250
|
+
|
|
251
|
+
Each collection has a well-defined purpose:
|
|
252
|
+
|
|
253
|
+
- **Signals** participate in matching and have accuracy/range specs.
|
|
254
|
+
- **Conditions** appear in SpecBand `when:` constraints but don't participate directly in matching logic.
|
|
255
|
+
- **Controls** are user-configurable but don't affect the fundamental capability.
|
|
256
|
+
- **Attributes** are hardware facts that may participate in matching (e.g. scope bandwidth must exceed signal frequency), but are never measured — they're just limits.
|
|
257
|
+
|
|
258
|
+
A dimension name can't appear in more than one of `signals` / `conditions` / `controls` — TesterKit won't load a capability with that overlap. A name in `attributes` doesn't collide with the others.
|
|
259
|
+
|
|
260
|
+
### Condition-Dependent Specs (SpecBand)
|
|
261
|
+
|
|
262
|
+
Instrument accuracy often varies with operating conditions. A DMM's AC voltage accuracy depends on the input frequency. A `SpecBand` captures this:
|
|
263
|
+
|
|
264
|
+
```yaml
|
|
265
|
+
signals:
|
|
266
|
+
voltage:
|
|
267
|
+
range: {min: 0.1, max: 750, unit: V}
|
|
268
|
+
accuracy: {pct_reading: 0.07, pct_range: 0.02} # default
|
|
269
|
+
bands:
|
|
270
|
+
- when:
|
|
271
|
+
frequency: {min: 3, max: 5, unit: Hz}
|
|
272
|
+
accuracy: {pct_reading: 0.35, pct_range: 0.03}
|
|
273
|
+
- when:
|
|
274
|
+
frequency: {min: 5, max: 300, unit: Hz}
|
|
275
|
+
accuracy: {pct_reading: 0.07, pct_range: 0.02}
|
|
276
|
+
- when:
|
|
277
|
+
frequency: {min: 300, max: 300000, unit: Hz}
|
|
278
|
+
accuracy: {pct_reading: 0.14, pct_range: 0.05}
|
|
279
|
+
conditions:
|
|
280
|
+
frequency:
|
|
281
|
+
range: {min: 3, max: 300000, unit: Hz}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The `when:` keys reference the flat union of `signals`, `conditions`, and `controls` on the parent capability — any sibling dimension name is valid. Multiple keys are ANDed (all must match). When no band matches, the top-level accuracy/resolution applies as a default.
|
|
285
|
+
|
|
286
|
+
### Canonical condition keys
|
|
287
|
+
|
|
288
|
+
`ConditionKey` is a shared vocabulary for the `conditions` dict (27 canonical keys derived from auditing 150+ instrument datasheets). It's not enforced at the model level — you can use any string — but matching across catalog entries is more reliable when authors converge on these names:
|
|
289
|
+
|
|
290
|
+
| Category | Keys |
|
|
291
|
+
|---|---|
|
|
292
|
+
| Universal | `frequency`, `temperature`, `humidity`, `calibration_interval` |
|
|
293
|
+
| Measurement config | `nplc`, `auto_zero`, `coupling`, `impedance`, `sense_mode`, `sample_rate`, `bandwidth`, `filter`, `gate_time`, `acquisition_mode`, `time_constant` |
|
|
294
|
+
| Signal | `signal_level`, `crest_factor` |
|
|
295
|
+
| Source / load | `load`, `input_voltage`, `voltage`, `current`, `duty_cycle`, `slew_rate`, `settling_time` |
|
|
296
|
+
| Sensor | `sensor`, `wavelength` |
|
|
297
|
+
| RF | `offset` |
|
|
298
|
+
|
|
299
|
+
## Channel Specification
|
|
300
|
+
|
|
301
|
+
Channels describe the physical topology of each instrument channel:
|
|
302
|
+
|
|
303
|
+
```yaml
|
|
304
|
+
# Structured channel topology (on catalog/instrument library):
|
|
305
|
+
channels:
|
|
306
|
+
"1":
|
|
307
|
+
label: "6V/5A Output"
|
|
308
|
+
terminals: [hi, lo, sense_hi, sense_lo] # Physical terminals
|
|
309
|
+
connector: binding_post # Connector type
|
|
310
|
+
ground: floating # Isolated from other channels
|
|
311
|
+
"2":
|
|
312
|
+
terminals: [hi, lo]
|
|
313
|
+
connector: binding_post
|
|
314
|
+
ground: floating
|
|
315
|
+
|
|
316
|
+
# On capabilities, channels is a plain list of keys:
|
|
317
|
+
capabilities:
|
|
318
|
+
- function: dc_voltage
|
|
319
|
+
direction: output
|
|
320
|
+
channels: ["1", "2"] # Which channels support this capability
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## 3-Tier Instrument Catalog
|
|
324
|
+
|
|
325
|
+
Capability data lives at three levels:
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
catalog/keysight_34461a.yaml ← Universal: "what can this MODEL do"
|
|
329
|
+
instruments/dmm_bench_001.yaml ← Unit-specific: serial, calibration, catalog_ref
|
|
330
|
+
stations/bench_01.yaml ← Project-local: role, driver, resource, catalog_ref
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
When a station instrument has `catalog_ref: keysight_34461a`, the matching engine resolves capabilities from the catalog entry — providing detailed range/accuracy data without requiring each station config to repeat it.
|
|
334
|
+
|
|
335
|
+
## Using the Matcher
|
|
336
|
+
|
|
337
|
+
### Python API
|
|
338
|
+
|
|
339
|
+
```python
|
|
340
|
+
from testerkit.matching.service import find_compatible_stations, check_station_compatibility
|
|
341
|
+
|
|
342
|
+
# Find all compatible stations (takes the loaded Part object)
|
|
343
|
+
matches = find_compatible_stations(part)
|
|
344
|
+
|
|
345
|
+
# Check specific station — takes id strings, returns dict | None
|
|
346
|
+
result = check_station_compatibility(part_id, station_id)
|
|
347
|
+
if result and not result["compatible"]:
|
|
348
|
+
for cap in result["missing"]:
|
|
349
|
+
print(f"Missing: {cap['direction']} {cap['function']}")
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
`find_compatible_stations(part)` takes a loaded `Part` object and returns a `list[StationMatch]`. `check_station_compatibility(part_id, station_id)` takes id strings and returns a `dict | None`; its `missing` value is a list of dicts shaped `{characteristic, function, direction}`.
|
|
353
|
+
|
|
354
|
+
### HTTP API
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
# Find all compatible stations
|
|
358
|
+
curl "http://localhost:8000/api/match?part_id=power_board"
|
|
359
|
+
|
|
360
|
+
# Check specific station
|
|
361
|
+
curl "http://localhost:8000/api/match?part_id=power_board&station_id=bench_1"
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Where this model comes from
|
|
365
|
+
|
|
366
|
+
The capability model draws on established test standards: signal-oriented thinking from IEEE 1641 (capabilities describe signals, not instruments; waveform shapes are parameters, not types), the comparator types and direction-pairing concept from ATML / IEEE 1671, and function names from the IVI Foundation instrument classes (DMM, Scope, FGen, DCPwr, RFSigGen). Parts and instruments use the same model, so matching pairs them directly — no translation step.
|
|
367
|
+
|
|
368
|
+
## Custom Instruments
|
|
369
|
+
|
|
370
|
+
When adding custom instruments, define their capabilities using the function-parameter model:
|
|
371
|
+
|
|
372
|
+
```yaml
|
|
373
|
+
# instruments/temp_logger.yaml
|
|
374
|
+
instrument:
|
|
375
|
+
type: temp_logger
|
|
376
|
+
name: Custom Temperature Logger
|
|
377
|
+
|
|
378
|
+
channels:
|
|
379
|
+
"T1": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
380
|
+
"T2": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
381
|
+
"T3": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
382
|
+
"T4": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
383
|
+
"T5": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
384
|
+
"T6": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
385
|
+
"T7": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
386
|
+
"T8": {terminals: [signal], connector: terminal_block, ground: shared}
|
|
387
|
+
|
|
388
|
+
capabilities:
|
|
389
|
+
- function: temperature
|
|
390
|
+
direction: input
|
|
391
|
+
signals:
|
|
392
|
+
temperature:
|
|
393
|
+
range: {min: -200, max: 850, unit: "°C"}
|
|
394
|
+
channels: ["T1", "T2", "T3", "T4", "T5", "T6", "T7", "T8"]
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## The full picture
|
|
398
|
+
|
|
399
|
+
```
|
|
400
|
+
Instrument catalog — what an instrument CAN do
|
|
401
|
+
──────────────────────────────────────────────
|
|
402
|
+
catalog_entry:
|
|
403
|
+
id: keysight_34461a
|
|
404
|
+
type: dmm
|
|
405
|
+
channels:
|
|
406
|
+
"1": {terminals: [hi, lo], connector: binding_post, ground: shared}
|
|
407
|
+
|
|
408
|
+
capabilities:
|
|
409
|
+
- function: dc_voltage ─┐
|
|
410
|
+
direction: input │ Capability
|
|
411
|
+
signals: │ (shared base class)
|
|
412
|
+
voltage: │
|
|
413
|
+
range: {min: 0, max: 1000, unit: V}
|
|
414
|
+
accuracy: {pct_reading: 0.0035}
|
|
415
|
+
resolution: {digits: 6.5}
|
|
416
|
+
|
|
417
|
+
Part spec — what the UUT NEEDS tested
|
|
418
|
+
────────────────────────────────────────
|
|
419
|
+
id: power_board_v1
|
|
420
|
+
pins:
|
|
421
|
+
VOUT: {name: "J1.3", net: "VOUT_3V3", role: signal}
|
|
422
|
+
|
|
423
|
+
characteristics:
|
|
424
|
+
rail_3v3:
|
|
425
|
+
function: dc_voltage ─┐
|
|
426
|
+
direction: output │ PartCharacteristic
|
|
427
|
+
pin: VOUT │ (extends Capability)
|
|
428
|
+
signals: │
|
|
429
|
+
voltage: │
|
|
430
|
+
value: 3.3 │
|
|
431
|
+
unit: V │
|
|
432
|
+
bands: │
|
|
433
|
+
- when: │
|
|
434
|
+
load: {min: 0, max: 1} │
|
|
435
|
+
accuracy: {pct_reading: 5.0}
|
|
436
|
+
|
|
437
|
+
Matching: dc_voltage OUTPUT ↔ dc_voltage INPUT
|
|
438
|
+
3.3 V within 0–1000 V range
|
|
439
|
+
0.0035% << 5% (instrument is more accurate)
|
|
440
|
+
MATCH
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
## Next Steps
|
|
444
|
+
|
|
445
|
+
- [Fixtures](fixtures.md) — Mapping UUT pins to instruments
|
|
446
|
+
- [Architecture](../overview/architecture.md) — System data flow
|
|
447
|
+
- [Custom drivers](../../how-to/configuration/custom-drivers.md) — Creating custom drivers
|