Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow thawing on a timer #609

Merged
merged 12 commits into from
Jun 26, 2024
Merged

Allow thawing on a timer #609

merged 12 commits into from
Jun 26, 2024

Conversation

DominicOram
Copy link
Contributor

@DominicOram DominicOram commented Jun 11, 2024

Fixes DiamondLightSource/hyperion#1418

Instructions to reviewer on how to test:

  1. Confirm thawer tests pass and covers required behaviour

Checks for reviewer

  • Would the PR title make sense to a scientist on a set of release notes
  • If a new device has been added does it follow the standards
  • If changing the API for a pre-existing device, ensure that any beamlines using this device have updated their Bluesky plans accordingly
  • Have the connection tests for the relevant beamline(s) been run via dodal connect ${BEAMLINE}

class ThawerStates(str, Enum):
OFF = "Off"
ON = "On"


class Thawer(StandardReadable):
class ThawingTimer(SignalRW[float]):
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd make it a Device rather than a SignalRW as we're not actually doing anything with the value here...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think a Movable is better because of #609 (comment)?

Copy link
Collaborator

@olliesilvester olliesilvester left a comment

Choose a reason for hiding this comment

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

Looks good, just one comment. It's a bit of a nitpick since I expect we'd pretty much always be controlling the thawer via this new function, rather than directly through the control PV. However, if someone did the latter, they may get confused

src/dodal/devices/thawer.py Show resolved Hide resolved
)


async def test_calling_stop_on_thawer_stops_thawing(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similar to my last comment, this test implies calling stop stops the thawing, but if haven't previously called thaw_for_time_s, then stop does nothing

Copy link
Collaborator

@olliesilvester olliesilvester left a comment

Choose a reason for hiding this comment

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

One comment, but looks good

src/dodal/devices/thawer.py Show resolved Hide resolved
class Thawer(StandardReadable):
class ThawingTimer(Device):
def __init__(self, control_signal: SignalRW[ThawerStates]) -> None:
super().__init__("thawing_timer")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should: I think super().__init__ should go at the end of the init function, just by convention

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, this is an odd one. When making a Device super must go at the end of the function because it will iterate through and change the names of the child signals to be device-signal. We probably want control to be given it's device name from Thawer rather than ThawingTimer, in which case the answer here is for ThawingTimer to not be a Device at all, which I have done and so now it doesn't need to call super at all

Copy link
Collaborator

@olliesilvester olliesilvester Jun 25, 2024

Choose a reason for hiding this comment

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

Deleted my previous comment as I don't think it's right. I would go back to what you had before, with __init__ before the self._control_signal = control_signal. I can't think of any other way which makes sense given that a Msg obj should have a name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That still doesn't work because ThawingTimer overwrites the name. But I might do that anyway and spin into a new issue to think of a better way of doing it.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I can't think of a good solution here. You could do

    def __init__(self, prefix: str, name: str = "") -> None:
        self.thaw_for_time_s = ThawingTimer(epics_signal_rw(ThawerStates, prefix + ":CTRL"))
        self.control = epics_signal_rw(ThawerStates, prefix + ":CTRL")
        super().__init__(name)

So you'd have two separate control signals pointing to the same PV, and the names would reflect where they're from. But I can imagine creating two signals to the same PV might cause issues

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

I've proposed a fix over in that ticket, but I was wondering why ThawingTimer is a separate object here? Could you move the set method into the Thawer and dispense with the ThawingTimer completely? @olliesilvester suggested they both needed to be set in bluesky/ophyd-async#410 (comment) but I don't see the other set method here...

Copy link
Collaborator

@olliesilvester olliesilvester Jun 25, 2024

Choose a reason for hiding this comment

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

Sorry, yeah, my previous comment was a bit misleading as there isn't a set on Thawer right now. If we did have a Thawer.set it would just be setting the control signal to on or off, (no timer)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As @olliesilvester said, the Thawer has two modes of operation:

  1. The plan will turn it on/off
  2. The plan will turn it on via the timer then not turn it off itself

I feel like having the set on the Thawer doing number 2 is really not obvious. You would logically expect it to be doing number 1.

Copy link
Collaborator

@olliesilvester olliesilvester left a comment

Choose a reason for hiding this comment

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

Thanks. I agree about Thawer setting the name for control

@DominicOram
Copy link
Contributor Author

Failing tests are on main also so unrelated to this I believe

Copy link
Collaborator

@olliesilvester olliesilvester left a comment

Choose a reason for hiding this comment

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

Looks good!

@DominicOram DominicOram merged commit 3a36f4d into main Jun 26, 2024
9 of 11 checks passed
@DominicOram DominicOram deleted the hyperion_1418_thawer_on_a_timer branch June 26, 2024 14:49
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.

Turn thawing on after robot load
5 participants