Skip to content

feat(device): FeatureNotSupportedException + v3.5.0 floor + -113 backstop on GetSdCardStorageAsync - #288

Merged
tylerkron merged 2 commits into
mainfrom
claude/github-issue-254-c13625
Jul 10, 2026
Merged

tylerkron merged 2 commits into
mainfrom
claude/github-issue-254-c13625

Conversation

@tylerkron

Copy link
Copy Markdown
Contributor

Summary

  • Adds DeviceFeature enum (AnalogOutput, SdStorageQuery, CapabilityDocument) and a typed FeatureNotSupportedException (Feature, RequiredVersion, ActualVersion, Board), per ADR 0001's proposed API shape.
  • Adds DaqifiDevice.MinSupportedFirmware (v3.5.0) constant and a live-evaluated IsFirmwareVersionSupported property (reads Metadata.FirmwareVersion fresh on every access — not cached, per the ADR's "don't cache version-derived flags" rule).
  • GetSdCardStorageAsync now parses the numeric SCPI error code out of the existing **ERROR: <code>, "<msg>" line and, on -113 ("Undefined header"), throws FeatureNotSupportedException instead of the generic SdCardOperationException. This is a deliberate behavior change flagged in the ADR: old-firmware failures on this command move from a generic exception to a distinct typed one — callers catching SdCardOperationException broadly will need to also catch FeatureNotSupportedException.
  • Retry logic is untouched: a persistent -113 still retries once (like today's -200 case) before translating.

Implements the primary near-term deliverable from ADR 0001 (docs/adr/0001-firmware-feature-gating.md, #252). Closes #254.

Testing

  • dotnet build -c Release: 0 warnings, 0 errors (TreatWarningsAsErrors).
  • dotnet test (net9.0 + net10.0): 1340 passed, 0 failed, 2 skipped (real-hardware-only tests).
  • New unit tests: FeatureNotSupportedException construction/message, DaqifiDevice.IsFirmwareVersionSupported (unknown/unparseable/below-floor/at-or-above-floor/live-reevaluation), and GetSdCardStorageAsync throwing FeatureNotSupportedException on a persistent -113 (with Feature/RequiredVersion/ActualVersion/Board populated from device metadata).
  • Verified on hardware (Nyquist1, firmware v3.6.2, /dev/cu.usbmodem1101): connect + short stream and GetSdCardStorageAsync() happy paths are unaffected by this change, and IsFirmwareVersionSupported correctly reports true against the real reported firmware string. The -113 path itself couldn't be exercised on this device since its firmware is above the v3.5.0 floor — that wire format was already empirically verified in fix(scpi)!: send SYST:STORage:SD:FILE for SD logging (firmware v3.5.0+) #253.

Test plan

  • dotnet build -c Release — 0 warnings, 0 errors
  • dotnet test — 1340 passed, 0 failed, 2 skipped
  • Bench-tested against real Nyquist1 hardware (firmware v3.6.2)
  • Smoke test against firmware below the v3.5.0 floor to directly exercise FeatureNotSupportedException (no such device on hand for this PR)

🤖 Generated with Claude Code

…stop on GetSdCardStorageAsync

Implements ADR 0001's primary near-term deliverable (closes #254): a
DeviceFeature enum, a typed FeatureNotSupportedException, and a
MinSupportedFirmware (v3.5.0) floor + live IsFirmwareVersionSupported
helper on DaqifiDevice. GetSdCardStorageAsync now parses the SCPI error
code and throws FeatureNotSupportedException on -113 "Undefined header"
instead of the generic SdCardOperationException, so old-firmware
devices get a clear, typed signal rather than a generic error.

Verified on hardware (Nyquist1, firmware v3.6.2): connect/stream/
GetSdCardStorageAsync happy paths are unaffected, and
IsFirmwareVersionSupported correctly reports true against the real
firmware version string.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tylerkron
tylerkron requested a review from a team as a code owner July 10, 2026 17:29
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add firmware feature-gating exception and -113 handling for SD storage query

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Introduce DeviceFeature and FeatureNotSupportedException for typed feature gating.
• Add a v3.5.0 minimum firmware floor and a live IsFirmwareVersionSupported helper.
• Translate SCPI -113 (“Undefined header”) on SD storage query into
 FeatureNotSupportedException.
Diagram

graph TD
A["Caller"] --> B["GetSdCardStorageAsync"] --> C[("Device firmware")]
C --> D{"SCPI error -113?"}
D -- "yes" --> E["Throw FeatureNotSupportedException"]
D -- "no" --> F["Parse response / throw SdCardOperationException"]
subgraph Legend
direction LR
_m["Method"] ~~~ _fw[("Firmware")] ~~~ _dec{"Decision"}
end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Preflight version-gate (fail fast before sending SCPI)
  • ➕ Avoids round-trips on obviously unsupported firmware
  • ➕ Keeps behavior consistent across all gated features
  • ➖ Depends on firmware version being already known/parseable
  • ➖ Can incorrectly block commands that happen to work on older firmware
  • ➖ Conflicts with the ADR’s preference to avoid caching version-derived flags
2. Centralize SCPI error parsing/translation in the transport/protocol layer
  • ➕ One shared implementation for extracting numeric error codes
  • ➕ Easier to reuse for other commands and other SCPI errors
  • ➖ Bigger refactor and broader blast radius than needed for this deliverable
  • ➖ Harder to attach feature-specific context (which command/feature triggered it)
3. Expose a structured SCPI error object instead of parsing strings
  • ➕ Eliminates string parsing and makes error handling more robust
  • ➕ Enables richer diagnostics and consistent error mapping
  • ➖ Requires protocol changes and likely wider public API impact
  • ➖ More work than warranted for adding a single feature-gating backstop

Recommendation: The chosen approach (translate wire-level -113 into FeatureNotSupportedException at the call site) is a good near-term fit: it uses the firmware’s authoritative signal, avoids relying on potentially-missing version metadata, and keeps the change localized to the one command currently needing a feature gate. Consider later centralization of SCPI error parsing if additional commands need similar mapping.

Files changed (8) +343 / -0

Enhancement (4) +174 / -0
DaqifiDevice.csAdd minimum supported firmware constant and live IsFirmwareVersionSupported +21/-0

Add minimum supported firmware constant and live IsFirmwareVersionSupported

• Introduces 'DaqifiDevice.MinSupportedFirmware' (v3.5.0) as the library’s tested firmware floor. Adds a live-evaluated 'IsFirmwareVersionSupported' property that parses 'Metadata.FirmwareVersion' on every access and treats missing/unparseable values as unsupported/unknown.

src/Daqifi.Core/Device/DaqifiDevice.cs

DaqifiStreamingDevice.csTranslate SCPI -113 on SD storage query into typed feature exception +41/-0

Translate SCPI -113 on SD storage query into typed feature exception

• Adds SCPI error code parsing ('TryParseScpiErrorCode') and a constant for -113 “Undefined header”. Updates 'GetSdCardStorageAsync' to throw 'FeatureNotSupportedException' (with feature/version/board context) when a -113 is observed, while preserving existing retry behavior and generic error handling for other failures.

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs

DeviceFeature.csIntroduce DeviceFeature enum for firmware/hardware-gated capabilities +29/-0

Introduce DeviceFeature enum for firmware/hardware-gated capabilities

• Adds a new 'DeviceFeature' enum to identify gated capabilities such as analog output, SD storage query, and capability document queries. Intended to be carried by 'FeatureNotSupportedException' to give callers a stable discriminator for unsupported functionality.

src/Daqifi.Core/Device/DeviceFeature.cs

FeatureNotSupportedException.csAdd FeatureNotSupportedException with feature/version/board context +83/-0

Add FeatureNotSupportedException with feature/version/board context

• Adds a sealed exception type representing unsupported device features, with strongly-typed 'Feature' plus optional 'RequiredVersion', 'ActualVersion', and 'Board'. Implements a message builder that explains required vs. reported firmware and includes board information when available.

src/Daqifi.Core/Device/FeatureNotSupportedException.cs

Tests (3) +168 / -0
DaqifiDeviceFirmwareSupportTests.csAdd tests for minimum firmware floor and live support evaluation +73/-0

Add tests for minimum firmware floor and live support evaluation

• Introduces unit tests validating 'DaqifiDevice.MinSupportedFirmware' is v3.5.0 and that 'IsFirmwareVersionSupported' returns false for missing/unparseable/below-floor versions. Adds a regression test ensuring the property is evaluated live from current 'Metadata.FirmwareVersion' rather than cached.

src/Daqifi.Core.Tests/Device/DaqifiDeviceFirmwareSupportTests.cs

FeatureNotSupportedExceptionTests.csAdd unit tests for FeatureNotSupportedException properties and message +72/-0

Add unit tests for FeatureNotSupportedException properties and message

• Adds tests ensuring constructor arguments populate 'Feature', 'RequiredVersion', 'ActualVersion', and 'Board', and that optional fields remain null when not provided. Verifies message formatting includes feature/version details and handles unknown versions/board inclusion.

src/Daqifi.Core.Tests/Device/FeatureNotSupportedExceptionTests.cs

SdCardOperationsTests.csTest -113 “Undefined header” is translated to FeatureNotSupportedException +23/-0

Test -113 “Undefined header” is translated to FeatureNotSupportedException

• Adds a new test for 'GetSdCardStorageAsync' where a persistent '**ERROR: -113' triggers 'FeatureNotSupportedException' after the existing single retry. Asserts the exception carries feature, required firmware floor, actual firmware string, and board type from metadata.

src/Daqifi.Core.Tests/Device/SdCard/SdCardOperationsTests.cs

Documentation (1) +1 / -0
ISdCardOperations.csDocument FeatureNotSupportedException for GetSdCardStorageAsync contract +1/-0

Document FeatureNotSupportedException for GetSdCardStorageAsync contract

• Updates XML documentation for 'GetSdCardStorageAsync' to include 'FeatureNotSupportedException' when firmware does not recognize the storage query (SCPI -113). This clarifies a deliberate behavior change for callers catching exceptions.

src/Daqifi.Core/Device/SdCard/ISdCardOperations.cs

@qodo-code-review

qodo-code-review Bot commented Jul 10, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 📜 Skill insights (0)

Context used

Grey Divider


Remediation recommended

1. SCPI code parsing mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
TryParseScpiErrorCode requires a ':' to extract the numeric SCPI code, so a space/tab-delimited
error line (e.g. "**ERROR -113,...") will not be recognized as -113 and GetSdCardStorageAsync will
throw SdCardOperationException instead of FeatureNotSupportedException.
Code

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[R1567-1583]

+        /// <summary>
+        /// Parses the numeric error code out of a SCPI error line matched by
+        /// <see cref="IsScpiErrorLine"/> — e.g. <c>**ERROR: -113, "Undefined header"</c> or
+        /// <c>ERROR: -113,"Undefined header"</c>. The code is the text between the first colon
+        /// and the following comma (if any).
+        /// </summary>
+        private static bool TryParseScpiErrorCode(string line, out int code)
+        {
+            code = 0;
+            var colonIndex = line.IndexOf(':');
+            if (colonIndex < 0) return false;
+
+            var afterColon = line[(colonIndex + 1)..];
+            var commaIndex = afterColon.IndexOf(',');
+            var codeSpan = (commaIndex >= 0 ? afterColon[..commaIndex] : afterColon).Trim();
+            return int.TryParse(codeSpan, NumberStyles.Integer, CultureInfo.InvariantCulture, out code);
+        }
Relevance

⭐⭐⭐ High

Repo previously accepted more robust SCPI numeric parsing/terminator logic (PR #185) and SCPI error
handling tightening (PR #182).

PR-#185
PR-#182

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new -113 translation depends on parsing an int code from lastScpiError, but the parser fails
unless the line contains a colon, while the shared classifier considers space/tab-delimited ERROR
tokens valid error lines.

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1108-1120]
src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1567-1583]
src/Daqifi.Core/Device/ScpiResponseClassifier.cs[15-44]
PR-#185

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`TryParseScpiErrorCode` only parses error codes when a colon (`:`) exists in the SCPI error line. However, the repo’s shared SCPI error-line classifier treats `:` / space / tab as valid delimiters after the `**ERROR`/`ERROR` token. If firmware emits a valid space/tab-delimited form (e.g. `**ERROR -113, ...`), the new `-113` feature-gating translation will not trigger.

### Issue Context
- `GetSdCardStorageAsync` relies on `TryParseScpiErrorCode(lastScpiError, ...)` to detect `-113` and throw `FeatureNotSupportedException`.
- `ScpiResponseClassifier` explicitly allows space/tab as SCPI delimiters.

### Fix Focus Areas
- src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1567-1583]
- src/Daqifi.Core/Device/ScpiResponseClassifier.cs[15-45]
- src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1108-1120]

### Suggested fix
Update `TryParseScpiErrorCode` to:
- Trim leading whitespace.
- Strip the leading `**ERROR` or `ERROR` token.
- Skip optional delimiter characters (`:`, space, tab).
- Parse the signed integer up to the first comma (or end-of-line).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Misleading required firmware version ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
GetSdCardStorageAsync throws FeatureNotSupportedException with RequiredVersion =
MinSupportedFirmware (3.5.0), but DeviceFeature.SdStorageQuery documentation says the storage query
requires firmware >= v3.4.6b1, so the exception metadata/message can mislead callers about the
minimum version needed.
Code

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[R1115-1118]

+                throw new FeatureNotSupportedException(
+                    DeviceFeature.SdStorageQuery,
+                    MinSupportedFirmware,
+                    Metadata.FirmwareVersion,
Relevance

⭐⭐⭐ High

Team has accepted fixing misleading version/documentation mismatches before (PR #98). Likely will
align RequiredVersion with feature docs.

PR-#98

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The code passes the global min supported floor (3.5.0) as the feature’s required version, while the
feature’s own documentation and the exception’s property docs describe RequiredVersion as
feature-specific minimum.

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1108-1119]
src/Daqifi.Core/Device/DeviceFeature.cs[17-21]
src/Daqifi.Core/Device/FeatureNotSupportedException.cs[23-26]
src/Daqifi.Core/Device/DaqifiDevice.cs[47-56]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The `FeatureNotSupportedException.RequiredVersion` contract is “minimum firmware version required for the feature, if known”, but the SdStorageQuery path always supplies `MinSupportedFirmware` (3.5.0) even though the feature enum docs state SdStorageQuery requires >= v3.4.6b1. This makes `RequiredVersion` inconsistent and potentially misleading.

### Issue Context
You can resolve this either by:
1) Passing the feature-specific minimum version for SdStorageQuery, or
2) Updating the SdStorageQuery documentation (and/or exception docs) to match the intended meaning (e.g., “minimum supported by daqifi-core” instead of “minimum that introduced the command”).

### Fix Focus Areas
- src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1108-1119]
- src/Daqifi.Core/Device/DeviceFeature.cs[17-21]
- src/Daqifi.Core/Device/FeatureNotSupportedException.cs[23-26]
- src/Daqifi.Core/Device/DaqifiDevice.cs[47-56]

### Suggested fix
Introduce a per-feature minimum (e.g. `SdStorageQueryMinFirmware = new FirmwareVersion(3,4,6,"b",1)`) and pass that into the exception, or adjust the SdStorageQuery doc comment to state it requires `>= MinSupportedFirmware` if that’s the intended semantic.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. No connect-time firmware-too-old flag ✗ Dismissed 📎 Requirement gap ≡ Correctness
Description
The new firmware floor is defined, but Connect() does not evaluate/report a single "firmware too
old" state at connect time for UI consumption as required. This can cause callers to only discover
unsupported firmware later via per-operation failures rather than a one-time connect-time indicator.
Code

src/Daqifi.Core/Device/DaqifiDevice.cs[R47-66]

+        /// <summary>
+        /// Minimum firmware version daqifi-core is built and tested against (ADR 0001,
+        /// docs/adr/0001-firmware-feature-gating.md). Every SCPI command daqifi-core issues today
+        /// exists on all firmware at or above this floor, so a device below it gets best-effort
+        /// behavior: an individual command may still work, but any that don't are surfaced as a
+        /// typed <see cref="FeatureNotSupportedException"/> via the wire-level <c>-113</c>
+        /// "Undefined header" backstop, rather than a guarantee up front.
+        /// </summary>
+        public static readonly FirmwareVersion MinSupportedFirmware = new(3, 5, 0, null, 0);
+
+        /// <summary>
+        /// Gets a value indicating whether the connected device's reported firmware version meets
+        /// <see cref="MinSupportedFirmware"/>. Evaluated live against <see cref="Metadata"/> on every
+        /// access — not cached — so it always reflects the most recently reported version rather than
+        /// a stale snapshot. Returns <c>false</c> if the firmware version has not yet been reported or
+        /// does not parse; callers should treat that as "unknown", not "confirmed unsupported".
+        /// </summary>
+        public bool IsFirmwareVersionSupported =>
+            FirmwareVersion.TryParse(Metadata.FirmwareVersion, out var parsed) && parsed >= MinSupportedFirmware;
+
Relevance

⭐⭐ Medium

Some history favors connect-time readiness checks (PR #200), but no prior connect-time
firmware-floor UI flag evidence.

PR-#200

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance ID 1 requires a connect-time "firmware too old" indication. The PR adds
MinSupportedFirmware and explicitly documents a best-effort approach rather than an up-front
guarantee, and Connect() contains no firmware version evaluation or one-time state surfacing.

Introduce a minimum supported firmware floor (v3.5.0) and detect firmware-too-old at connect
src/Daqifi.Core/Device/DaqifiDevice.cs[47-66]
src/Daqifi.Core/Device/DaqifiDevice.cs[241-273]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
PR Compliance requires detecting firmware below `v3.5.0` at connect time and surfacing/recording that state exactly once for UI consumption.

## Issue Context
`DaqifiDevice.MinSupportedFirmware` and `IsFirmwareVersionSupported` were added, but `Connect()` does not evaluate firmware support or emit/store a single connect-time indication.

## Fix Focus Areas
- src/Daqifi.Core/Device/DaqifiDevice.cs[47-66]
- src/Daqifi.Core/Device/DaqifiDevice.cs[241-273]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
4. Missing Supports(DeviceFeature) API ✗ Dismissed 📎 Requirement gap ⚙ Maintainability
Description
The PR introduces DeviceFeature but does not add a Supports(DeviceFeature) API that evaluates
lazily from current board/firmware without caching version-derived booleans. This leaves callers
without the required feature-gating entrypoint described by the compliance checklist.
Code

src/Daqifi.Core/Device/DeviceFeature.cs[R1-28]

+namespace Daqifi.Core.Device
+{
+    /// <summary>
+    /// Identifies a firmware- or hardware-gated capability that a device may or may not
+    /// support, carried by <see cref="FeatureNotSupportedException"/> (ADR 0001,
+    /// docs/adr/0001-firmware-feature-gating.md). New members are added only when
+    /// daqifi-core starts consuming a command that some supported device might lack.
+    /// </summary>
+    public enum DeviceFeature
+    {
+        /// <summary>
+        /// Analog output (<c>SOURce:VOLTage:LEVel</c> / <c>CONFigure:DAC:*</c>). Board-gated:
+        /// Nyquist3 only.
+        /// </summary>
+        AnalogOutput,
+
+        /// <summary>
+        /// SD card storage capacity query (<c>SYSTem:STORage:SD:SPACe?</c>). Firmware-gated:
+        /// requires firmware &gt;= v3.4.6b1, at or below the <see cref="DaqifiDevice.MinSupportedFirmware"/> floor.
+        /// </summary>
+        SdStorageQuery,
+
+        /// <summary>
+        /// Capability document query (<c>CONFigure:CAPabilities:JSON?</c> /
+        /// <c>:APIVersion?</c>). Firmware-gated: requires firmware &gt;= v3.5.0.
+        /// </summary>
+        CapabilityDocument
+    }
Relevance

⭐⭐ Medium

No historical evidence for requiring a Supports(DeviceFeature) API; could be deferred despite
ticket/compliance mention.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Compliance ID 5 requires a lazily evaluated Supports(DeviceFeature) API. The PR adds the
DeviceFeature enum but the base device interface does not expose any Supports(DeviceFeature)
method, indicating the required API is missing.

Ensure Supports(DeviceFeature) evaluates lazily from current board and firmware without caching version-derived booleans
src/Daqifi.Core/Device/DeviceFeature.cs[1-28]
src/Daqifi.Core/Device/IDevice.cs[12-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Compliance requires a `Supports(DeviceFeature)` API that computes support at call time from the latest `Metadata` (board + firmware), without caching firmware-version-derived booleans.

## Issue Context
`DeviceFeature` was added, but the device interfaces/classes do not expose a `Supports(DeviceFeature)` method for callers to query feature availability.

## Fix Focus Areas
- src/Daqifi.Core/Device/DeviceFeature.cs[1-28]
- src/Daqifi.Core/Device/IDevice.cs[12-59]
- src/Daqifi.Core/Device/DaqifiDevice.cs[47-66]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

5. Unknown board included in error ✓ Resolved 🐞 Bug ◔ Observability
Description
GetSdCardStorageAsync always passes Metadata.DeviceType into FeatureNotSupportedException, so when
metadata hasn’t been populated yet the exception will include Board=Unknown and message text like
“Board: Unknown.” rather than omitting the board entirely.
Code

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[R1117-1119]

+                    MinSupportedFirmware,
+                    Metadata.FirmwareVersion,
+                    Metadata.DeviceType);
Relevance

⭐⭐ Medium

No clear historical pattern on omitting “Unknown” optional metadata from exception messages; could
be considered minor.

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Metadata’s default device type is Unknown, but the exception’s Board field is described as present
only when known; passing Unknown causes it to appear in the thrown exception/message even when the
board is not actually identified.

src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1115-1119]
src/Daqifi.Core/Device/DeviceMetadata.cs[30-34]
src/Daqifi.Core/Device/FeatureNotSupportedException.cs[35-38]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`FeatureNotSupportedException.Board` is intended to be set “if known”, but `GetSdCardStorageAsync` always supplies `Metadata.DeviceType`, whose default is `DeviceType.Unknown`. This makes the exception’s message noisier and can imply the board is known when it isn’t.

### Issue Context
`DeviceMetadata.DeviceType` is a non-nullable enum and defaults to `Unknown`, so call sites should translate that sentinel to `null` when populating optional diagnostics fields.

### Fix Focus Areas
- src/Daqifi.Core/Device/DaqifiStreamingDevice.cs[1115-1119]
- src/Daqifi.Core/Device/DeviceMetadata.cs[30-34]
- src/Daqifi.Core/Device/FeatureNotSupportedException.cs[35-38]

### Suggested fix
Pass `board: Metadata.DeviceType != DeviceType.Unknown ? Metadata.DeviceType : null` (or adjust `BuildMessage` to suppress `Unknown`).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

Comment thread src/Daqifi.Core/Device/DaqifiDevice.cs
Comment thread src/Daqifi.Core/Device/DeviceFeature.cs
Comment thread src/Daqifi.Core/Device/DaqifiStreamingDevice.cs
Comment thread src/Daqifi.Core/Device/DaqifiStreamingDevice.cs
Comment thread src/Daqifi.Core/Device/DaqifiStreamingDevice.cs Outdated
- TryParseScpiErrorCode now accepts ':', space, or tab as the
  delimiter after the ERROR/**ERROR token, matching the delimiters
  ScpiResponseClassifier already treats as valid — a space-delimited
  "**ERROR -113, ..." line was previously falling through to the
  generic SdCardOperationException instead of the typed
  FeatureNotSupportedException.
- GetSdCardStorageAsync now passes null (not DeviceType.Unknown) as
  the exception's Board when the device type hasn't been reported yet,
  since Board is documented as "if known".
- Clarify DeviceFeature.SdStorageQuery's doc comment: the command's
  actual introduction version (v3.4.6b1) differs from the version the
  exception reports (MinSupportedFirmware, v3.5.0) — intentional, per
  ADR 0001's example code, since the v3.5.0 floor is what daqifi-core
  actually guarantees.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tylerkron
tylerkron merged commit 4a7d0cd into main Jul 10, 2026
1 check passed
@tylerkron
tylerkron deleted the claude/github-issue-254-c13625 branch July 10, 2026 19:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: FeatureNotSupportedException + v3.5.0 floor + -113 backstop on GetSdCardStorageAsync

1 participant