Skip to content

Commit

Permalink
759 pressure jump devices collected updates (#812)
Browse files Browse the repository at this point in the history
* Pressure jump cell removed manual pump control enums.

* Grouped valve open and close PVs under valve control.

* Pressure jump cell updated set_valve to use ValveControl.

* Pressure jump cell fixed index error on setting ValveOpenSeq value and updated pressure transducer  tests to match current naming.

* Pressure jump cell mapped open to open_seq in set_valve to simplify interface.

* Pressure jump cell set valve open requests to inactive after OPENSEQ_PULSE_LENGTH delay.
  • Loading branch information
barnettwilliam authored and stan-dot committed Nov 14, 2024
1 parent 6387004 commit 4dd37b8
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 45 deletions.
103 changes: 64 additions & 39 deletions src/dodal/devices/pressure_jump_cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,18 @@
ConfigSignal,
DeviceVector,
SignalR,
SignalRW,
StandardReadable,
)
from ophyd_async.epics.signal import epics_signal_r, epics_signal_rw

OPENSEQ_PULSE_LENGTH = 0.2

class PumpState(str, Enum):
MANUAL = "Manual"
AUTO_PRESSURE = "Auto Pressure"
AUTO_POSITION = "Auto Position"


class BusyState(str, Enum):
IDLE = "Idle"
BUSY = "Busy"


class TimerState(str, Enum):
TIMEOUT = "TIMEOUT"
COUNTDOWN = "COUNTDOWN"


class StopState(str, Enum):
CONTINUE = "CONTINUE"
STOP = "STOP"
Expand All @@ -49,12 +39,9 @@ class ValveControlRequest(str, Enum):
RESET = "Reset"


class PumpMotorControlRequest(str, Enum):
ENABLE = "Enable"
DISABLE = "Disable"
RESET = "Reset"
FORWARD = "Forward"
REVERSE = "Reverse"
class ValveOpenSeqRequest(int, Enum):
INACTIVE = 0
OPEN_SEQ = 1


class PumpMotorDirectionState(str, Enum):
Expand All @@ -80,11 +67,6 @@ class FastValveState(str, Enum):
NONE = "Unused"


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


@dataclass
class AllValvesControlState:
valve_1: ValveControlRequest | None = None
Expand Down Expand Up @@ -126,31 +108,36 @@ def __init__(
)
)

self.fast_valve_control: DeviceVector[SignalRW[FastValveControlRequest]] = (
DeviceVector(
{
i: epics_signal_rw(FastValveControlRequest, f"{prefix}V{i}:CON")
for i in self.fast_valves
}
)
self.fast_valve_control: DeviceVector[FastValveControl] = DeviceVector(
{i: FastValveControl(f"{prefix}V{i}") for i in self.fast_valves}
)

self.valve_control: DeviceVector[SignalRW[ValveControlRequest]] = DeviceVector(
{
i: epics_signal_rw(ValveControlRequest, f"{prefix}V{i}:CON")
for i in self.slow_valves
}
self.valve_control: DeviceVector[ValveControl] = DeviceVector(
{i: ValveControl(f"{prefix}V{i}") for i in self.slow_valves}
)

super().__init__(name)

async def set_valve(
self, valve: int, value: ValveControlRequest | FastValveControlRequest
self,
valve: int,
value: ValveControlRequest | FastValveControlRequest,
):
if valve in self.slow_valves and isinstance(value, ValveControlRequest):
await self.valve_control[valve].set(value)
elif valve in self.fast_valves and isinstance(value, FastValveControlRequest):
await self.fast_valve_control[valve].set(value)
if valve in self.slow_valves and (isinstance(value, ValveControlRequest)):
if value == ValveControlRequest.OPEN:
await self.valve_control[valve].set(ValveOpenSeqRequest.OPEN_SEQ)
await asyncio.sleep(OPENSEQ_PULSE_LENGTH)
await self.valve_control[valve].set(ValveOpenSeqRequest.INACTIVE)
else:
await self.valve_control[valve].set(value)

elif valve in self.fast_valves and (isinstance(value, FastValveControlRequest)):
if value == FastValveControlRequest.OPEN:
await self.fast_valve_control[valve].set(ValveOpenSeqRequest.OPEN_SEQ)
await asyncio.sleep(OPENSEQ_PULSE_LENGTH)
await self.fast_valve_control[valve].set(ValveOpenSeqRequest.INACTIVE)
else:
await self.fast_valve_control[valve].set(value)

@AsyncStatus.wrap
async def set(self, value: AllValvesControlState):
Expand All @@ -163,6 +150,44 @@ async def set(self, value: AllValvesControlState):
)


class ValveControl(StandardReadable):
def __init__(self, prefix: str, name: str = "") -> None:
with self.add_children_as_readables():
self.close = epics_signal_rw(ValveControlRequest, prefix + ":CON")
self.open = epics_signal_rw(ValveOpenSeqRequest, prefix + ":OPENSEQ")

super().__init__(name)

def set(self, value: ValveControlRequest | ValveOpenSeqRequest) -> AsyncStatus:
setStatus = None

if isinstance(value, ValveControlRequest):
setStatus = self.close.set(value)
elif isinstance(value, ValveOpenSeqRequest):
setStatus = self.open.set(value)

return setStatus


class FastValveControl(StandardReadable):
def __init__(self, prefix: str, name: str = "") -> None:
with self.add_children_as_readables():
self.close = epics_signal_rw(FastValveControlRequest, prefix + ":CON")
self.open = epics_signal_rw(ValveOpenSeqRequest, prefix + ":OPENSEQ")

super().__init__(name)

def set(self, value: FastValveControlRequest | ValveOpenSeqRequest) -> AsyncStatus:
setStatus = None

if isinstance(value, FastValveControlRequest):
setStatus = self.close.set(value)
elif isinstance(value, ValveOpenSeqRequest):
setStatus = self.open.set(value)

return setStatus


class Pump(StandardReadable):
def __init__(self, prefix: str, name: str = "") -> None:
with self.add_children_as_readables():
Expand Down
162 changes: 156 additions & 6 deletions tests/devices/unit_tests/test_pressure_jump_cell.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from unittest.mock import ANY

import asyncio
import pytest
from ophyd_async.core import DeviceCollector, assert_reading, set_mock_value

from dodal.devices.pressure_jump_cell import (
FastValveControlRequest,
FastValveState,
PressureJumpCell,
PumpMotorDirectionState,
ValveControlRequest,
ValveOpenSeqRequest,
ValveState,
)

Expand Down Expand Up @@ -59,12 +62,159 @@ async def test_reading_pjumpcell_includes_read_fields_valves(
)


async def test_reading_pjumpcell_includes_config_fields_valves(
cell: PressureJumpCell,
):
set_mock_value(
cell.all_valves_control.valve_control[1].close, ValveControlRequest.CLOSE
)
set_mock_value(
cell.all_valves_control.valve_control[3].close, ValveControlRequest.OPEN
)
set_mock_value(
cell.all_valves_control.valve_control[1].open, ValveOpenSeqRequest.INACTIVE
)
set_mock_value(
cell.all_valves_control.valve_control[3].open, ValveOpenSeqRequest.OPEN_SEQ
)

set_mock_value(
cell.all_valves_control.fast_valve_control[5].close,
FastValveControlRequest.DISARM,
)
set_mock_value(
cell.all_valves_control.fast_valve_control[6].close, FastValveControlRequest.ARM
)
set_mock_value(
cell.all_valves_control.fast_valve_control[5].open,
ValveOpenSeqRequest.INACTIVE,
)
set_mock_value(
cell.all_valves_control.fast_valve_control[6].open, ValveOpenSeqRequest.OPEN_SEQ
)

await assert_reading(
cell.all_valves_control.valve_control[1],
{
"pjump-all_valves_control-valve_control-1-close": {
"value": ValveControlRequest.CLOSE,
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-all_valves_control-valve_control-1-open": {
"value": ValveOpenSeqRequest.INACTIVE,
"timestamp": ANY,
"alarm_severity": 0,
},
},
)


async def test_pjumpcell_set_valve_sets_valve_fields(
cell: PressureJumpCell,
):
# Set some initial values
set_mock_value(
cell.all_valves_control.valve_control[1].close, ValveControlRequest.RESET
)
set_mock_value(
cell.all_valves_control.valve_control[1].open, ValveOpenSeqRequest.INACTIVE
)

set_mock_value(
cell.all_valves_control.fast_valve_control[6].close,
FastValveControlRequest.RESET,
)

set_mock_value(
cell.all_valves_control.fast_valve_control[6].open, ValveOpenSeqRequest.INACTIVE
)

# Set new values

await cell.all_valves_control.set_valve(1, ValveControlRequest.CLOSE)
await cell.all_valves_control.set_valve(6, FastValveControlRequest.ARM)

await asyncio.gather(
cell.all_valves_control.set_valve(1, ValveControlRequest.OPEN),
cell.all_valves_control.set_valve(6, FastValveControlRequest.OPEN),

# Check valves requested to open are set to OPEN_SEQ on initially calling
# set_valve()
assert_reading(
cell.all_valves_control.valve_control[1],
{
"pjump-all_valves_control-valve_control-1-open": {
"value": ValveOpenSeqRequest.OPEN_SEQ,
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-all_valves_control-valve_control-1-close": {
"value": ANY,
"timestamp": ANY,
"alarm_severity": 0,
},
},
),
assert_reading(
cell.all_valves_control.fast_valve_control[6],
{
"pjump-all_valves_control-fast_valve_control-6-open": {
"value": ValveOpenSeqRequest.OPEN_SEQ,
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-all_valves_control-fast_valve_control-6-close": {
"value": ANY,
"timestamp": ANY,
"alarm_severity": 0,
},
},
)

)

# Check slow valves have been set to the new value and valves requested to open are
# set to INACTIVE after set_valve() completes
await assert_reading(
cell.all_valves_control.valve_control[1],
{
"pjump-all_valves_control-valve_control-1-open": {
"value": ValveOpenSeqRequest.INACTIVE,
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-all_valves_control-valve_control-1-close": {
"value": ValveControlRequest.CLOSE,
"timestamp": ANY,
"alarm_severity": 0,
},
},
)

# Check fast valves have been set to the new value and valves requested to open are
# set to INACTIVE after set_valve() completes
await assert_reading(
cell.all_valves_control.fast_valve_control[6],
{
"pjump-all_valves_control-fast_valve_control-6-close": {
"value": FastValveControlRequest.ARM,
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-all_valves_control-fast_valve_control-6-open": {
"value": ValveOpenSeqRequest.INACTIVE,
"timestamp": ANY,
"alarm_severity": 0,
},
},
)


async def test_reading_pjumpcell_includes_read_fields_pump(
cell: PressureJumpCell,
):
set_mock_value(cell.pump.pump_position, 100)
# set_mock_value(cell.pump.pump_forward_limit, LimitSwitchState.OFF)
# set_mock_value(cell.pump.pump_backward_limit, LimitSwitchState.ON)
set_mock_value(
cell.pump.pump_motor_direction,
PumpMotorDirectionState.FORWARD,
Expand Down Expand Up @@ -129,7 +279,7 @@ async def test_reading_pjumpcell_includes_read_fields_transducers(
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-pressure_transducers-1-beckhoff_voltage": {
"pjump-pressure_transducers-1-slow_beckhoff_voltage_readout": {
"value": 2.51,
"timestamp": ANY,
"alarm_severity": 0,
Expand All @@ -154,7 +304,7 @@ async def test_reading_pjumpcell_includes_read_fields_transducers(
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-pressure_transducers-2-beckhoff_voltage": {
"pjump-pressure_transducers-2-slow_beckhoff_voltage_readout": {
"value": 2.52,
"timestamp": ANY,
"alarm_severity": 0,
Expand All @@ -179,7 +329,7 @@ async def test_reading_pjumpcell_includes_read_fields_transducers(
"timestamp": ANY,
"alarm_severity": 0,
},
"pjump-pressure_transducers-3-beckhoff_voltage": {
"pjump-pressure_transducers-3-slow_beckhoff_voltage_readout": {
"value": 2.53,
"timestamp": ANY,
"alarm_severity": 0,
Expand Down

0 comments on commit 4dd37b8

Please sign in to comment.