Skip to content

demo: convert temperature controller to getter/setter style - #411

Open
coretl wants to merge 7 commits into
refactorfrom
refactor-issue-404
Open

demo: convert temperature controller to getter/setter style#411
coretl wants to merge 7 commits into
refactorfrom
refactor-issue-404

Conversation

@coretl

@coretl coretl commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Closes #404

Retargets Tutorial 2 (getter/setter) onto the existing temperature controller demo rather than adding a second module: the existing src/fastcs/demo/controllers.py is converted to the getter/setter style in place and renamed to src/fastcs/demo/temperature_attr.py, matching how the other demo modules are named (device + style, not framework concept). One temperature backend, one temperature module.

Current-API baseline in the intended shape: TemperatureProtocol / TemperatureRampProtocol carry one method per wire command, each attribute's TemperatureIORef carries the command-building callables (read_cmd/write_cmd), and a single generic TemperatureIO just invokes them — mirroring fastcs-thorlabs-mff (MFFAttributeIO/MFFAttributeIORef/ThorlabsAPTProtocol). read_cmd/write_cmd are the getter/setter this foreshadows: #392 promotes them onto AttrRW(getter=..., setter=...) and deletes the IO/ref wrapper, while the protocol classes survive unchanged. Response parsing (attr.dtype(...)) is inline in TemperatureIO.update, not a response_handler callable.

Attributes move from the class body into __init__. That is what earns the style: each ramp bakes its index into its own protocol instance, instead of the shared IO dispatching on a name string plus a suffix. The composition and methods rungs are carried through unchanged — the ControllerVector of TemperatureRampControllers from #409, @scan and @command — so this module now covers both the getter/setter rung and the composition rung (#390), and the README ladder collapses from five modules to four accordingly.

Behaviour is preserved: same attribute names and hierarchy, same 0.2 s default poll period, same two scan groups. The launch type: in fastcs.yaml is derived from the top-level package rather than the submodule, so fastcs.TemperatureController and the checked-in schema.json survive the rename unchanged (verified by regenerating the schema).

Instructions to reviewer on how to test:

  1. uv run pytest tests/demo/test_temperature_attr.py -v
  2. python -m fastcs.demo run src/fastcs/demo/fastcs.yaml against the sim (tickit all src/fastcs/demo/simulation/temp_controller.yaml)

Checks for reviewer

Notes


Generated by Claude Code

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR adds the temperature-simulator example and tests, and it uses the current callback-IO baseline called for in #404.
Out of Scope Changes check ✅ Passed The changes stay focused on the temperature demo example and its tests, with no unrelated scope evident.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a temperature controller demo that uses getter/setter-style attribute wiring.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-issue-404

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.

@codecov

codecov Bot commented Jul 22, 2026

Copy link
Copy Markdown

Codecov Report

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

Additional details and impacted files
@@            Coverage Diff            @@
##           refactor     #411   +/-   ##
=========================================
  Coverage     91.25%   91.25%           
=========================================
  Files            72       72           
  Lines          2892     2892           
=========================================
  Hits           2639     2639           
  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: 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 `@src/fastcs/demo/temperature_attr.py`:
- Around line 76-77: Update the async close method to reset the controller’s
_connected state to False after awaiting self.connection.close(), so subsequent
connection status checks correctly report the closed state.
🪄 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 Plus

Run ID: a64717b0-dfc5-439f-a5e0-0a883dacae7c

📥 Commits

Reviewing files that changed from the base of the PR and between 3da025f and 4dbaf83.

📒 Files selected for processing (2)
  • src/fastcs/demo/temperature_attr.py
  • tests/demo/test_temperature_attr.py

Comment thread src/fastcs/demo/temperature_attr.py
Comment thread src/fastcs/demo/temperature_attr.py
Comment thread tests/demo/test_temperature_attr.py Outdated

@shihab-dls shihab-dls 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.

Just one comment regarding # type: ignore. This is idiomatic fastcs logic, with good tests, and It does show obscurity with passing setters and getters into an AttributeIORef, which I think is a good starting point. Approving.

Comment thread tests/demo/test_temperature_attr.py Outdated
@coretl coretl changed the title demo: getter/setter-in-init temperature attr example demo: convert temperature controller to getter/setter style Aug 3, 2026
claude and others added 7 commits August 3, 2026 12:22
Add temperature_attr.py: a small temperature controller with
per-attribute IO (a fresh AttributeIO/AttributeIORef pair per
attribute) wired directly in __init__ rather than shared class-body
declarations, foreshadowing the AttrRW(getter=, setter=) constructor
params landing in #392. Baseline against the current callback-IO API.

Closes #404
Address CodeRabbit review comment: close() closed the socket but left
_connected True, so a subsequent status check would still report
connected.
…ape)

Rewrites the getter/setter baseline to the intended shape: one generic
TemperatureIO drives every attribute, and each TemperatureIORef carries the
command-building callables (read_cmd/write_cmd) sourced from a single
TemperatureProtocol class - mirroring fastcs-thorlabs-mff's
MFFAttributeIO/MFFAttributeIORef/ThorlabsAPTProtocol.

This is the honest precursor to #392's AttrRW(getter=, setter=): read_cmd/
write_cmd ARE the getter/setter, promoted onto the constructor when the IO/ref
wrapper is deleted, while TemperatureProtocol survives unchanged.

Replaces the previous per-attribute AttributeIO subclasses (RampRateIO/PowerIO),
which hardcoded commands and foreshadowed nothing. Response parsing (float())
is inline in TemperatureIO.update rather than a response_handler callable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LgnovZ7FWY8YptwqiufTbX
…ttr tests

The project type-checks with pyright (standard mode), which does not flag
assigning an AsyncMock over a bound method here, and `method-assign` is a
mypy error code pyright never emits. pyright src tests is clean without them.
Rather than adding a second temperature module, retarget #404 onto the
existing `fastcs.demo.controllers` so there is one temperature demo.

`TemperatureProtocol`/`TemperatureRampProtocol` carry one method per wire
command, `TemperatureIORef` carries the `read_cmd`/`write_cmd` callables,
and a single generic `TemperatureIO` just invokes them - the same shape as
`fastcs-thorlabs-mff`, and the honest precursor to `AttrRW(getter=…,
setter=…)` in #392.

Attributes move from the class body into `__init__`, which is what lets
each ramp bake its index into its own protocol instance instead of the IO
dispatching on a `name` string plus suffix. Composition, `@scan` and
`@command` are unchanged, so this module now covers both the getter/setter
rung and the composition rung; the README ladder collapses accordingly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Match the naming of the other demo modules (hello_world.py,
temperature_scpi.py, eiger.py), which are named for the device and the
style they demonstrate rather than for the framework concept.

Updates the importers: `fastcs.demo.__main__`, the test module, the
README ladder and the docs nitpick-ignore entry. The launch `type:` in
fastcs.yaml is derived from the top-level package, not the submodule, so
`fastcs.TemperatureController` and the checked-in schema.json are
unaffected (verified by regenerating the schema).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coretl
coretl force-pushed the refactor-issue-404 branch from 0ef888d to e73453b Compare August 3, 2026 12:25
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.

3 participants