Skip to content

Decode declared EPICS DBR_CHAR waveforms as text - #645

Merged
xmap merged 1 commit into
mainfrom
worktree-epics-char-waveform
Aug 11, 2026
Merged

Decode declared EPICS DBR_CHAR waveforms as text#645
xmap merged 1 commit into
mainfrom
worktree-epics-char-waveform

Conversation

@xmap

@xmap xmap commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • EPICS gives a char waveform holding a NUL-terminated string (tomoscan's ScanStatus, FileName, FilePath, FullFileName) and one holding raw bytes (an NTNDArray image) the same wire type, so EpicsCaControlPort could only ever unpack it as an integer tuple.
  • A deployment now declares which addresses on a route actually carry text via ControlPortRoute.text_addresses; declared addresses decode to Measurement(kind="Scalar", value=<str>), everything else is unaffected.
  • Needed to read 2-BM's tomoscan status/filename PVs at all, ahead of wiring an observer for them.
  • Guards element_count > 1 so the declaration stays inert (rather than raising) against a length-1 char waveform, which aioca collapses to a non-iterable scalar type — caught by code review before commit and covered by a regression test.

Test plan

  • pytest tests/unit/operation/test_control_port_config.py tests/integration/test_epics_ca_control_port.py — 47 passed
  • pytest tests/integration/test_caproto_control_port.py tests/integration/test_epics_pva_control_port.py — confirms the shared soft-IOC db addition doesn't disturb sibling adapters
  • pytest tests/architecture — 30408 passed, 621 skipped
  • ruff check / ruff format / pyright / tach check all clean
  • naming review (R1-R6) on text_addresses — no violations
  • code review — one finding (scalar DBR_CHAR crash), fixed, verified against a live soft IOC

🤖 Generated with Claude Code

EPICS gives a char waveform holding a NUL-terminated string (e.g.
tomoscan's ScanStatus, FileName) and one holding raw bytes (an
NTNDArray image) the same wire type, so EpicsCaControlPort could
only ever unpack it as an integer tuple. A deployment now declares
which addresses on a route actually carry text via
ControlPortRoute.text_addresses; declared addresses decode to
Measurement(kind="Scalar", value=<str>), everything else is
unaffected. Needed to read 2-BM's tomoscan status/filename PVs at
all ahead of wiring an observer for them.

Guards element_count > 1 so the declaration stays inert (rather than
raising) against a length-1 char waveform, which aioca collapses to
a non-iterable scalar type.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  apps/api/src/cora/infrastructure
  control_port_route.py
  apps/api/src/cora/operation/adapters
  control_port_config.py
  epics_ca_control_port.py 507
Project Total  

This report was generated by python-coverage-comment-action

@xmap
xmap merged commit 2717a8a into main Aug 11, 2026
19 checks passed
@xmap
xmap deleted the worktree-epics-char-waveform branch August 11, 2026 17:54
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.

1 participant