embeint.htf
Station runtime

Capture DUT values

Add structured identifiers and measurements to a DUT test report.

Station runtime v0.3.0 can attach named values to test reports on HTF v0.1.4. Use captures for identifiers or measurements that should be searchable without parsing console logs. Each observation keeps its DUT, run, lane, stage, optional subtest, capture time, and configuration revision.

Map a built-in stage output

Add a capture mapping to a stage. The mapping's key is the report field; its value is the output produced by that stage:

stages:
  - name: Read hardware ID
    kind: hardware_id
    programmer: jlink_1
    capture:
      device.hardware_id: hardware_id

Configure jlink_1 locally with a supported target as described in Station configuration. Only explicit captures are persisted; other context outputs remain available to later stages. If this stage does not produce hardware_id, HTF records a capture warning. It does not reuse an earlier stage's output or change the hardware outcome.

An existing infuse_validation_rtt stage can capture modem outputs with this mapping; retain its programmer, transport, and test settings:

capture:
  modem.imei: validation.modem.imei
  sim.iccid: validation.modem.iccid
  sim.imsi: validation.modem.imsi
  modem.model: validation.modem.model
  modem.firmware_version: validation.modem.firmware_version

The validator exports VAL fields as validation.<test>.<field> and recognises modem INFO identifiers. A MODEM PASS can verify modem values even if another subtest fails. Contradictory modem values remain unverified.

Capture in a custom stage

After reading a value from your hardware, call the stage context:

context.capture("modem.imei", imei)
context.capture("sim.iccid", iccid)

Return the usual StageResult. Captures inherit the stage's pass/fail outcome by default. Set verified=True with subtest="MODEM" only after that subtest successfully validates the value:

context.capture("modem.imei", imei, verified=True, subtest="MODEM")

Captures that inherit a failed or interrupted stage outcome remain unverified. An explicitly verified successful subtest can still contribute values when the overall stage fails or is interrupted. Conflicting values within a stage are always unverified. Use separate keys, such as bluetooth.hardware_id and modem.hardware_id, for different components or parallel lanes.

Field limits

ItemLimit
Field keyUp to 128 characters; lowercase names such as modem.imei, with letters, digits, and underscores in each segment. Each segment starts with a letter.
ValueA non-empty string or integer, stored as a string; up to 512 UTF-16 code units on the server.
Subtest nameUp to 128 UTF-16 code units on the server.
ObservationsUp to 64 per stage and 1,024 per run.

Pass long identifiers and values with leading zeros as strings. ASCII characters each use one UTF-16 unit; characters such as many emoji use two. The Python runtime counts Unicode code points, so a value or subtest with those characters can pass its local length check and still exceed the server limit.

context.capture() returns False and adds a warning for an invalid value or a local limit violation; the hardware result remains intact. Identical captures with the same metadata within a stage are coalesced. Keep credentials out of captures as well as logs.

Inspect a local result

A caller of run_once() can inspect structured data directly:

report = result.report()           # JSON-ready stages, observations, and warnings
values = result.captured_values    # Successful values from this run
observations = result.observations

Calls without a server run ID retain captures in this local result but omit them from MQTT messages. Use a run started through HTF for production capture history.

Keep reports across disconnects

Capture-bearing messages are written to .htf-cache/report-outbox/<station-id> before upload. Keep the directory on persistent storage, writable by the station account. Listening stations retry after disconnects and restarts, with backoff from 10 seconds to 10 minutes. The station removes a report only after the server acknowledges its database commit.

Permanent rejections move to rejected/ with the original envelope and reason. The active queue holds 10,000 reports; additional messages wait in deferred/. Provide disk space for all three directories. A disk-write failure logs report_storage_failed and attempts live delivery, but that report has no durable disk copy. Captures are persisted at stage completion or interruption, rather than at every hardware read.

See DUT capture history to inspect reports, retests, and identifier changes. Follow Upgrade a station before enabling captures on an existing jig.