Skip to content

feat: allow aliases to be passed to ca transport#385

Merged
shihab-dls merged 8 commits into
mainfrom
ca_aliases
Jun 15, 2026
Merged

feat: allow aliases to be passed to ca transport#385
shihab-dls merged 8 commits into
mainfrom
ca_aliases

Conversation

@shihab-dls

@shihab-dls shihab-dls commented May 28, 2026

Copy link
Copy Markdown
Contributor

Closes #384

This PR allows passing aliases to the ca transport. An Example would be:

transport:
  - epicsca:
      aliases:
         - PV_TO_ALIAS: "ALIAS"

Summary by CodeRabbit

  • New Features
    • Added EPICS CA alias support via a new aliases transport option, registering alternate PV names for attributes, command PVs, and readback (*_RBV) variants.
    • Aliases are validated to prevent duplicate alias values; overly long alias names are skipped with a warning.
  • Tests
    • Added coverage for alias registration for write, readback (_RBV), and command PVs, plus updated IOC initialization and expectations.
  • Documentation
    • Updated the published EPICS CA options/schema to include the new aliases field.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an aliases mapping to EpicsCAOptions, passes it from EpicsCATransport into EpicsCAIOC, and registers EPICS record aliases when creating read/write and command PVs; demo schema, tests, and example SoftIOC usage updated.

Changes

EPICS CA Aliases Support

Layer / File(s) Summary
Configuration contract and schema
src/fastcs/transports/epics/options.py, src/fastcs/demo/schema.json, tests/data/schema.json
EpicsCAOptions now includes an aliases: dict[str, str] field with a default empty dict; demo and test JSON schemas add the aliases property as an object of string values.
IOC alias support
src/fastcs/transports/epics/ca/ioc.py
EpicsCAIOC.__init__ accepts an aliases mapping, validates for duplicate alias values, and passes it to _create_and_link_attribute_pvs and _create_and_link_command_pvs; adds RBV_SUFFIX constant for readback PV aliasing; attribute and command PV wiring looks up per-PV aliases (including readback variants with suffix) and forwards them into factory functions, which conditionally register EPICS record aliases via _add_alias helper with name-length validation.
Transport configuration wiring
src/fastcs/transports/epics/ca/transport.py
EpicsCATransport.connect() now passes self.epicsca.aliases to EpicsCAIOC on construction.
Tests and example updates
tests/transports/epics/ca/test_softioc.py, tests/example_softioc.py, tests/transports/epics/ca/test_softioc_system.py
Adds unit tests asserting record.add_alias(...) is invoked for write, readback (with _RBV suffix), and command PVs; updates IOC construction and helper call sites to include aliases parameter; example SoftIOC configures epicsca.aliases; system test verifies alias and original PV name sync after writes in both directions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • DiamondLightSource/fastcs#360: Refactored EpicsCAIOC multi-controller PV-prefix handling; this PR builds on top of that foundation to add PV alias wiring.

Suggested reviewers

  • coretl

Poem

🐰 With twitching nose, I hop with glee,
Aliases sprout on every PV!
Read, write, command—each gets its twin,
_RBV suffixed, where it should spin.
ADOdin rejoins—the aliases begin!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: allow aliases to be passed to ca transport' accurately describes the main feature addition—enabling alias configuration for the EPICS CA transport.
Linked Issues check ✅ Passed The PR implements alias support for CA transport as required by issue #384, allowing PVs to be aliased through FastCS configuration files without requiring changes to the fastcs-odin repository.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing alias support for the CA transport. Schema updates, option classes, IOC implementation, and tests all align with the stated objective.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ca_aliases

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.25%. Comparing base (c80a13c) to head (ebb7a8e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #385      +/-   ##
==========================================
+ Coverage   91.20%   91.25%   +0.05%     
==========================================
  Files          72       72              
  Lines        2875     2892      +17     
==========================================
+ Hits         2622     2639      +17     
  Misses        253      253              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/fastcs/transports/epics/ca/ioc.py (1)

138-154: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

AttrRW ignores explicit readback alias keys.

Line 138 only looks up the write PV key, then reuses it for both records. A mapping like PREFIX:MyPv_RBV -> ... is never read for AttrRW, so that config is silently ignored.

Suggested fix (preserve fallback behavior, allow explicit RBV aliases)
-            alias = aliases.get(f"{pv_prefix}:{pv_name}", None)
+            write_alias = aliases.get(f"{pv_prefix}:{pv_name}")
+            read_alias = aliases.get(f"{pv_prefix}:{pv_name}_RBV", write_alias)
             match attribute:
                 case AttrRW():
@@
                         _create_and_link_read_pv(
-                            pv_prefix, f"{pv_name}_RBV", attr_name, alias, attribute
+                            pv_prefix, f"{pv_name}_RBV", attr_name, read_alias, attribute
                         )
                         _create_and_link_write_pv(
-                            pv_prefix, pv_name, attr_name, alias, attribute
+                            pv_prefix, pv_name, attr_name, write_alias, attribute
                         )
                 case AttrR():
                     _create_and_link_read_pv(
                         pv_prefix,
                         pv_name,
                         attr_name,
-                        alias,
+                        aliases.get(f"{pv_prefix}:{pv_name}"),
                         attribute,
                     )
                 case AttrW():
                     _create_and_link_write_pv(
-                        pv_prefix, pv_name, attr_name, alias, attribute
+                        pv_prefix, pv_name, attr_name, aliases.get(f"{pv_prefix}:{pv_name}"), attribute
                     )

@@
-    if alias:
-        suffix = "_RBV" if pv_name.endswith("_RBV") else ""
-        record.add_alias(f"{alias}{suffix}")
+    if alias:
+        alias_name = (
+            f"{alias}_RBV" if pv_name.endswith("_RBV") and not alias.endswith("_RBV") else alias
+        )
+        record.add_alias(alias_name)

Also applies to: 187-190

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/fastcs/transports/epics/ca/ioc.py` around lines 138 - 154, The AttrRW
branch currently only looks up the alias for the write PV and reuses it for the
readback, so explicit RBV alias keys (e.g. f"{pv_prefix}:{pv_name}_RBV") are
ignored; change the code to separately resolve an RBV alias with fallback to the
write alias (e.g. rbv_alias = aliases.get(f"{pv_prefix}:{pv_name}_RBV", alias))
and pass rbv_alias to _create_and_link_read_pv while passing alias to
_create_and_link_write_pv; apply the same pattern to the other AttrRW handling
block referenced (around lines 187-190) so explicit RBV alias keys are honored
but the previous fallback behavior remains.
tests/transports/epics/ca/test_softioc.py (1)

628-632: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix stale expected call signature in waveform test (currently breaks CI).

_create_and_link_read_pv now receives (pv_prefix, pv_name, attr_name, alias, attribute), but this assertion still expects the old 4-arg call.

Proposed test fix
     create_mock.assert_called_once_with(
-        DEVICE, "Waveform1d", "waveform_1d", api.attributes["waveform_1d"]
+        DEVICE, "Waveform1d", "waveform_1d", None, api.attributes["waveform_1d"]
     )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/transports/epics/ca/test_softioc.py` around lines 628 - 632, The test's
expected call signature is stale: _create_and_link_read_pv now takes (pv_prefix,
pv_name, attr_name, alias, attribute), but the assertion in
tests/transports/epics/ca/test_softioc.py still expects 4 args; update the
create_mock.assert_called_once_with invocation used after EpicsCAIOC([api], {})
to include the missing alias argument between the attr_name ("waveform_1d") and
the attribute (api.attributes["waveform_1d"]) — use the same alias value the
code passes (e.g., the alias string or None) so the assertion matches
_create_and_link_read_pv's new signature.
🧹 Nitpick comments (1)
src/fastcs/transports/epics/options.py (1)

36-40: ⚡ Quick win

Update EpicsCAOptions docstring; it’s now outdated.

Line 38 says this options class is currently empty, but Line 44 adds aliases. This can mislead users reading config docs.

Proposed docstring update
 class EpicsCAOptions:
     """Channel-Access-specific options.
 
-    Currently empty: present so ``epicsca:`` survives in fastcs.yaml as the
-    transport discriminator key. Reserved for future CA-specific knobs.
+    Channel-Access-specific options configured under ``epicsca:`` in fastcs.yaml.
+    ``aliases`` maps generated PV names to alias base names.
     """
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/fastcs/transports/epics/options.py` around lines 36 - 40, Update the
EpicsCAOptions class docstring to reflect that the class is not empty: mention
the added "aliases" attribute and briefly describe its purpose (e.g., mapping
alternate transport names to this transport) and any intended usage in
fastcs.yaml; edit the docstring in the EpicsCAOptions definition so it no longer
claims the class is currently empty and instead documents the aliases field and
its role for the epicsca transport discriminator.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/fastcs/transports/epics/ca/ioc.py`:
- Around line 138-154: The AttrRW branch currently only looks up the alias for
the write PV and reuses it for the readback, so explicit RBV alias keys (e.g.
f"{pv_prefix}:{pv_name}_RBV") are ignored; change the code to separately resolve
an RBV alias with fallback to the write alias (e.g. rbv_alias =
aliases.get(f"{pv_prefix}:{pv_name}_RBV", alias)) and pass rbv_alias to
_create_and_link_read_pv while passing alias to _create_and_link_write_pv; apply
the same pattern to the other AttrRW handling block referenced (around lines
187-190) so explicit RBV alias keys are honored but the previous fallback
behavior remains.

In `@tests/transports/epics/ca/test_softioc.py`:
- Around line 628-632: The test's expected call signature is stale:
_create_and_link_read_pv now takes (pv_prefix, pv_name, attr_name, alias,
attribute), but the assertion in tests/transports/epics/ca/test_softioc.py still
expects 4 args; update the create_mock.assert_called_once_with invocation used
after EpicsCAIOC([api], {}) to include the missing alias argument between the
attr_name ("waveform_1d") and the attribute (api.attributes["waveform_1d"]) —
use the same alias value the code passes (e.g., the alias string or None) so the
assertion matches _create_and_link_read_pv's new signature.

---

Nitpick comments:
In `@src/fastcs/transports/epics/options.py`:
- Around line 36-40: Update the EpicsCAOptions class docstring to reflect that
the class is not empty: mention the added "aliases" attribute and briefly
describe its purpose (e.g., mapping alternate transport names to this transport)
and any intended usage in fastcs.yaml; edit the docstring in the EpicsCAOptions
definition so it no longer claims the class is currently empty and instead
documents the aliases field and its role for the epicsca transport
discriminator.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2da62478-6221-49d5-8c10-f756644d25ab

📥 Commits

Reviewing files that changed from the base of the PR and between c80a13c and 231f9b6.

📒 Files selected for processing (6)
  • src/fastcs/demo/schema.json
  • src/fastcs/transports/epics/ca/ioc.py
  • src/fastcs/transports/epics/ca/transport.py
  • src/fastcs/transports/epics/options.py
  • tests/data/schema.json
  • tests/transports/epics/ca/test_softioc.py

@coretl coretl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks fine.

Are there any system tests for CA? If so, then it should be added there too.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/transports/epics/ca/test_softioc_system.py`:
- Around line 48-56: The test incorrectly expects the AliasB_RBV readback to
follow writes to the setpoint PV; update the assertion logic in this test (using
ctxt.get and pv_prefix symbols) to verify alias equivalence only — i.e., assert
AliasB and the canonical PV (:B) match each other and separately assert
AliasB_RBV equals the canonical RBV value as provided by the IOC, instead of
expecting AliasB_RBV to become 10 after ctxt.put(f"{pv_prefix}:B", 10); locate
the assertions that reference f"{pv_prefix}:B", f"{pv_prefix}:AliasB" and
f"{pv_prefix}:AliasB_RBV" and change them to compare aliases to the canonical PV
rather than asserting RBV propagation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 291df94c-4ca1-4430-895c-0ed54b09c8c4

📥 Commits

Reviewing files that changed from the base of the PR and between 231f9b6 and 33ef1ff.

📒 Files selected for processing (3)
  • tests/example_softioc.py
  • tests/transports/epics/ca/test_softioc.py
  • tests/transports/epics/ca/test_softioc_system.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/transports/epics/ca/test_softioc.py

Comment thread tests/transports/epics/ca/test_softioc_system.py Outdated

@gilesknap gilesknap left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. One minor comment inline, plus this is for CA only. Won't PVA want it too?

Comment thread src/fastcs/transports/epics/ca/ioc.py Outdated
@shihab-dls

Copy link
Copy Markdown
Contributor Author

Looks good. One minor comment inline, plus this is for CA only. Won't PVA want it too?

I think @coretl and I agreed that, for now at least, CA is the only transport that required aliasing, as we're doing this for backwards compatibility with GDA.

@shihab-dls shihab-dls requested review from coretl and gilesknap June 15, 2026 09:56
@gilesknap

Copy link
Copy Markdown
Contributor

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/fastcs/transports/epics/options.py (1)

36-40: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the docstring to reflect the new aliases field.

The docstring still states "Currently empty" but the class now contains the aliases field.

📝 Proposed docstring update
 `@dataclass`
 class EpicsCAOptions:
-    """Channel-Access-specific options.
-
-    Currently empty: present so ``epicsca:`` survives in fastcs.yaml as the
-    transport discriminator key. Reserved for future CA-specific knobs.
-    """
+    """Channel-Access-specific options.
+
+    Attributes:
+        aliases: Mapping of canonical PV names to alias names for Channel Access records.
+    """
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/fastcs/transports/epics/options.py` around lines 36 - 40, The docstring
for the class at lines 36-40 in src/fastcs/transports/epics/options.py
incorrectly states "Currently empty" when the class now contains an `aliases`
field. Update the docstring to remove the "Currently empty" statement and
instead document the purpose and usage of the `aliases` field that is now
present in the class.
src/fastcs/transports/epics/ca/ioc.py (1)

140-153: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Validate alias names against EPICS name length constraints.

Alias names retrieved from the configuration are not validated against EPICS_MAX_NAME_LENGTH. If an alias exceeds 60 characters, the underlying record.add_alias() call may fail at runtime.

🛡️ Proposed validation
             alias = aliases.get(f"{pv_prefix}:{pv_name}", None)
+            if alias is not None and len(alias) > EPICS_MAX_NAME_LENGTH:
+                logger.warning(
+                    f"Alias '{alias}' for {pv_prefix}:{pv_name} exceeds"
+                    f" {EPICS_MAX_NAME_LENGTH} characters and will be ignored"
+                )
+                alias = None
             match attribute:
                 case AttrRW():
                     if full_pv_name_length > (EPICS_MAX_NAME_LENGTH - 4):

Apply similar validation at line 249 for command PV aliases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/fastcs/transports/epics/ca/ioc.py` around lines 140 - 153, Alias names
retrieved from the configuration via aliases.get() are not validated against
EPICS_MAX_NAME_LENGTH before being used. Add validation checks for both the
alias variable and alias_rbv variable to ensure they do not exceed
EPICS_MAX_NAME_LENGTH, similar to the validation already performed for
full_pv_name_length. If either alias exceeds the limit, log a warning and
disable the attribute before the alias is passed to record.add_alias(),
preventing runtime failures.
🧹 Nitpick comments (2)
tests/transports/epics/ca/test_softioc.py (1)

70-114: ⚖️ Poor tradeoff

Consider adding negative test cases for alias validation.

The new tests verify the happy path where record.add_alias is called with a valid alias. Consider adding tests that verify behavior when:

  • An alias exceeds EPICS_MAX_NAME_LENGTH
  • An alias conflicts with an existing PV name

These tests would help ensure the validation suggested in ioc.py works correctly.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/transports/epics/ca/test_softioc.py` around lines 70 - 114, Add
negative test cases to verify alias validation behavior for the three PV
creation functions (_create_and_link_write_pv, _create_and_link_read_pv, and
_create_and_link_command_pv). For each function, add tests that verify the
behavior when an alias exceeds EPICS_MAX_NAME_LENGTH and when an alias conflicts
with an existing PV name, ensuring that appropriate validation errors or
exceptions are raised in these edge cases.
tests/transports/epics/ca/test_softioc_system.py (1)

48-51: ⚡ Quick win

Consider testing bidirectional alias access and the _RBV alias.

The test verifies that reading from AliasB returns the same value as the canonical PV after writing to B. Consider also:

  • Writing to AliasB and reading from B to confirm bidirectional access
  • Verifying the AliasB_RBV alias points to B_RBV (the readback configured in example_softioc.py)
🧪 Suggested additional assertions
     # Assert alias. Aliases do not show up in PVI structure
     assert ctxt.get(f"{pv_prefix}:B") == ctxt.get(f"{pv_prefix}:AliasB") == 0
     ctxt.put(f"{pv_prefix}:B", 10)
     assert ctxt.get(f"{pv_prefix}:AliasB") == 10
+    # Test bidirectional access
+    ctxt.put(f"{pv_prefix}:AliasB", 20)
+    assert ctxt.get(f"{pv_prefix}:B") == 20
+    # Verify RBV alias points to readback
+    assert (
+        ctxt.get(f"{pv_prefix}:B_RBV")
+        == ctxt.get(f"{pv_prefix}:AliasB_RBV")
+    )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/transports/epics/ca/test_softioc_system.py` around lines 48 - 51, The
test currently only verifies reading from AliasB after writing to the canonical
PV B, but it does not test bidirectional alias behavior or readback aliases.
After the existing assertions, add two additional test scenarios: first, write a
value to the AliasB alias and then read from the canonical B PV to confirm the
write is reflected bidirectionally; second, add assertions to verify that the
AliasB_RBV readback alias correctly points to B_RBV by getting and potentially
setting values through this readback alias path, ensuring complete alias
coverage including both the main alias and its associated readback alias
counterpart.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/fastcs/transports/epics/ca/ioc.py`:
- Around line 151-153: The automatic readback PV alias lookup using RBV_SUFFIX
in the aliases.get() call at the specified location lacks documentation. Add a
code comment above or near the aliases.get() call that explains the implicit
behavior: that for read-write attributes (AttrRW), the code automatically
appends RBV_SUFFIX to construct the readback PV alias key, requiring users to
configure both the base setpoint alias and the RBV-suffixed readback alias when
setting up read-write attributes. Alternatively or additionally, update the
EpicsCAOptions.aliases docstring to document this automatic suffix aliasing
behavior for read-write attributes.

---

Outside diff comments:
In `@src/fastcs/transports/epics/ca/ioc.py`:
- Around line 140-153: Alias names retrieved from the configuration via
aliases.get() are not validated against EPICS_MAX_NAME_LENGTH before being used.
Add validation checks for both the alias variable and alias_rbv variable to
ensure they do not exceed EPICS_MAX_NAME_LENGTH, similar to the validation
already performed for full_pv_name_length. If either alias exceeds the limit,
log a warning and disable the attribute before the alias is passed to
record.add_alias(), preventing runtime failures.

In `@src/fastcs/transports/epics/options.py`:
- Around line 36-40: The docstring for the class at lines 36-40 in
src/fastcs/transports/epics/options.py incorrectly states "Currently empty" when
the class now contains an `aliases` field. Update the docstring to remove the
"Currently empty" statement and instead document the purpose and usage of the
`aliases` field that is now present in the class.

---

Nitpick comments:
In `@tests/transports/epics/ca/test_softioc_system.py`:
- Around line 48-51: The test currently only verifies reading from AliasB after
writing to the canonical PV B, but it does not test bidirectional alias behavior
or readback aliases. After the existing assertions, add two additional test
scenarios: first, write a value to the AliasB alias and then read from the
canonical B PV to confirm the write is reflected bidirectionally; second, add
assertions to verify that the AliasB_RBV readback alias correctly points to
B_RBV by getting and potentially setting values through this readback alias
path, ensuring complete alias coverage including both the main alias and its
associated readback alias counterpart.

In `@tests/transports/epics/ca/test_softioc.py`:
- Around line 70-114: Add negative test cases to verify alias validation
behavior for the three PV creation functions (_create_and_link_write_pv,
_create_and_link_read_pv, and _create_and_link_command_pv). For each function,
add tests that verify the behavior when an alias exceeds EPICS_MAX_NAME_LENGTH
and when an alias conflicts with an existing PV name, ensuring that appropriate
validation errors or exceptions are raised in these edge cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97f8dd9a-8636-4c34-8834-b6a29022caf0

📥 Commits

Reviewing files that changed from the base of the PR and between c80a13c and 0afe333.

📒 Files selected for processing (8)
  • src/fastcs/demo/schema.json
  • src/fastcs/transports/epics/ca/ioc.py
  • src/fastcs/transports/epics/ca/transport.py
  • src/fastcs/transports/epics/options.py
  • tests/data/schema.json
  • tests/example_softioc.py
  • tests/transports/epics/ca/test_softioc.py
  • tests/transports/epics/ca/test_softioc_system.py

Comment thread src/fastcs/transports/epics/ca/ioc.py
@gilesknap

gilesknap commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

@shihab-dls I feel that the _RBV is still possibly confusing:

  1. its predicated on the type of the attrubute but you don't specify that in the config - only the name
  2. RW assume that they can add _RBV (for the readback) and alias the demand and readback
  3. R only takes the name verbatim which I take to mean _RBV is included

I can't remember - if the RW attribute readback name is not a simple _RBV suffix, does that mean the attributes need to be declared as separate R and W? If not then 2 would break. Either way their are some assumptions here that don't immediately jump out.

Maybe we don't care?

@shihab-dls

shihab-dls commented Jun 15, 2026

Copy link
Copy Markdown
Contributor Author

@shihab-dls I feel that the _RBV is still possibly confusing:

1. its predicated on the type of the attrubute but you don't specify that in the config - only the name

2. RW assume that they can add _RBV (for the readback) and alias the demand and readback

3. R only takes the name verbatim which I take to mean _RBV is included

I can't remember - if the RW attribute readback name is not a simple _RBV suffix, does that mean the attributes need to be declared as separate R and W? If not then 2 would break. Either way their are some assumptions here that don't immediately jump out.

Maybe we don't care?

It is indeed the case that, if you need an AttrRW with different PV names for the setpoint and readback, then you need to make a separate AttrW and AttrR; making an AttrRW currently implies that you intend to have a setpoint and an _RBV. This does seem quite lacking, and maybe we need readback PV overrides on AttrRWs. I'll make an issue to address this, but for this PRs scope I think we can just work with this implication in mind.

There is a case where we want to alias:

ID:PV: "ID:SomeAlias"
ID:PV_RBV: "ID:AnotherAlias"

where our aliased PVs need to be Different for AttrRWs. This is likely, as legacy IOCs can have odd PV naming. Because of this, this comment of yours is very valid, and we shouldn't handle making the alias _RBVs ourselves. This is why the current implementation checks for an alias assigned to a readback PV, instead of making the readback alias itself. This way, a list of aliases you provide must be complete, and no additional aliases are created internally.

EDIT: Either way, I should document this somewhere in the fastcs docs. I'll add that to the new issue I'll create about AttrRWs, just so it doesn't block this PR.

@gilesknap gilesknap left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That seems fine to me. Approved.

@shihab-dls shihab-dls merged commit 508d8af into main Jun 15, 2026
18 of 19 checks passed
@shihab-dls shihab-dls deleted the ca_aliases branch June 15, 2026 15:35
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.

Alias PVs to ADOdin

3 participants