DAQ: MAJOR: Refactored mounting service
This commit is contained in:
1 parent
ff609bc68d
commit
0b03c984bd
4 files changed
+282
-221
No files matched your search
+65
-221
@@ -56,6 +56,7 @@ from aare.common.sample_geometry import SampleGeometryModel
|
||||
from aare.daq.operations.face_detection import FaceDetectionContext, FaceDetectionService, FaceDetectionResult
|
||||
from aare.daq.operations.loop_centering import LoopCenteringService, LoopCenteringContext
|
||||
from aare.daq.operations.loop_centering.models import LoopCenteringSettings
|
||||
from aare.daq.operations.mounting import MountingContext, MountingService
|
||||
|
||||
from aare.devices.area_detector import AutoEnum
|
||||
from aare.devices.jfjoch import JFJochWrapper
|
||||
@@ -123,7 +124,7 @@ class AareDAQ:
|
||||
self._automation_last_sample_name = ""
|
||||
self._automation_samples_in_queue = 0
|
||||
self._last_mount_error_message = ""
|
||||
self.__reset_mount_failure_counter("DAQ startup")
|
||||
self._create_mounting_service().reset_mount_failure_counter("DAQ startup")
|
||||
|
||||
def _is_hardware_failure(self, error: Exception) -> bool:
|
||||
return isinstance(
|
||||
@@ -567,52 +568,52 @@ class AareDAQ:
|
||||
),
|
||||
logger=logger,
|
||||
)
|
||||
#
|
||||
# def _create_mounting_service(self):
|
||||
# return MountingService(
|
||||
# context=MountingContext(
|
||||
# cfg=self.__cfg,
|
||||
# devs=self.__devs,
|
||||
# mount_position=ABR_POS_MOUNT,
|
||||
# ),
|
||||
# logger=logger,
|
||||
# )
|
||||
#
|
||||
# def _create_raster_service(self):
|
||||
# return RasterService(
|
||||
# context=RasterContext(
|
||||
# cfg=self.__cfg,
|
||||
# devs=self.__devs,
|
||||
# mlbox=self.__mlbox,
|
||||
# jfjoch=self.__jfjoch,
|
||||
# aare=self.__aare,
|
||||
# sample_provider=lambda: self.sample,
|
||||
# sample_geometry_provider=lambda: self.sample_geometry,
|
||||
# status_provider=lambda: self.status,
|
||||
# set_state=self.__set_state,
|
||||
# save_screenshot_db=self.save_screenshot_db,
|
||||
# upload_raster_diffraction_preview=self._upload_raster_diffraction_preview,
|
||||
# auto_center_line_scan_top_left=self._auto_center_line_scan_top_left,
|
||||
# ml_bounding_box=self.__ml_bounding_box,
|
||||
# ),
|
||||
# logger=logger,
|
||||
# )
|
||||
#
|
||||
# def _create_rotation_service(self):
|
||||
# return RotationService(
|
||||
# context=RotationContext(
|
||||
# cfg=self.__cfg,
|
||||
# devs=self.__devs,
|
||||
# jfjoch=self.__jfjoch,
|
||||
# aare=self.__aare,
|
||||
# sample_provider=lambda: self.sample,
|
||||
# sample_geometry_provider=lambda: self.sample_geometry,
|
||||
# status_provider=lambda: self.status,
|
||||
# set_state=self.__set_state,
|
||||
# save_screenshot_db=self.save_screenshot_db,
|
||||
# ),
|
||||
# logger=logger,
|
||||
# )
|
||||
|
||||
def _create_mounting_service(self):
|
||||
return MountingService(
|
||||
context=MountingContext(
|
||||
cfg=self.__cfg,
|
||||
devs=self.__devs,
|
||||
mount_position=ABR_POS_MOUNT,
|
||||
),
|
||||
logger=logger,
|
||||
)
|
||||
|
||||
def _create_raster_service(self):
|
||||
return RasterService(
|
||||
context=RasterContext(
|
||||
cfg=self.__cfg,
|
||||
devs=self.__devs,
|
||||
mlbox=self.__mlbox,
|
||||
jfjoch=self.__jfjoch,
|
||||
aare=self.__aare,
|
||||
sample_provider=lambda: self.sample,
|
||||
sample_geometry_provider=lambda: self.sample_geometry,
|
||||
status_provider=lambda: self.status,
|
||||
set_state=self.__set_state,
|
||||
save_screenshot_db=self.save_screenshot_db,
|
||||
upload_raster_diffraction_preview=self._upload_raster_diffraction_preview,
|
||||
auto_center_line_scan_top_left=self._auto_center_line_scan_top_left,
|
||||
ml_bounding_box=self.__ml_bounding_box,
|
||||
),
|
||||
logger=logger,
|
||||
)
|
||||
|
||||
def _create_rotation_service(self):
|
||||
return RotationService(
|
||||
context=RotationContext(
|
||||
cfg=self.__cfg,
|
||||
devs=self.__devs,
|
||||
jfjoch=self.__jfjoch,
|
||||
aare=self.__aare,
|
||||
sample_provider=lambda: self.sample,
|
||||
sample_geometry_provider=lambda: self.sample_geometry,
|
||||
status_provider=lambda: self.status,
|
||||
set_state=self.__set_state,
|
||||
save_screenshot_db=self.save_screenshot_db,
|
||||
),
|
||||
logger=logger,
|
||||
)
|
||||
|
||||
|
||||
#--------------------------------------------
|
||||
@@ -703,18 +704,29 @@ class AareDAQ:
|
||||
|
||||
if previous_sample is not None and previous_sample.db_id is not None:
|
||||
self.__aare.send_sample_event(previous_sample, SampleEventType.UNMOUNTING)
|
||||
|
||||
self.__set_state(BeamlineStateEnum.RobotSampleExchange)
|
||||
|
||||
if sample is not None and sample.db_id is not None:
|
||||
self.__aare.send_sample_event(sample, SampleEventType.MOUNTING)
|
||||
self.__mount(sample)
|
||||
|
||||
mounting_result = self._create_mounting_service().execute(target=sample)
|
||||
|
||||
if not mounting_result.success:
|
||||
raise mounting_result.error or MountingFailed(
|
||||
mounting_result.comment or "Mount failed"
|
||||
)
|
||||
|
||||
if previous_sample is not None and previous_sample.db_id is not None:
|
||||
self.__aare.send_sample_event(previous_sample, SampleEventType.UNMOUNTED)
|
||||
self.__set_state(BeamlineStateEnum.SampleAlignment)
|
||||
|
||||
if sample is not None and sample.db_id is not None:
|
||||
self.__aare.send_sample_event(sample, SampleEventType.MOUNTED)
|
||||
self.save_screenshot_db(sample.db_id, f"{sample.db_id}_mounted")
|
||||
self.__set_state(BeamlineStateEnum.SampleAlignment)
|
||||
return True
|
||||
|
||||
except TransformationInvalidException as e:
|
||||
self._last_mount_error_message = str(e) or "Mount failed"
|
||||
logger.error(f"Mount failed due to invalid transformation: {e}")
|
||||
@@ -725,14 +737,15 @@ class AareDAQ:
|
||||
event_type=SampleEventType.MOUNTFAILED,
|
||||
)
|
||||
raise
|
||||
|
||||
except Exception as e:
|
||||
self._last_mount_error_message = str(e) or "Mount failed"
|
||||
logger.error(f"Mount failed: {e}")
|
||||
|
||||
previous_sample_unmounted = (
|
||||
previous_sample is not None
|
||||
and previous_sample.db_id is not None
|
||||
and self._was_previous_sample_unmounted_since(mount_started_at)
|
||||
previous_sample is not None
|
||||
and previous_sample.db_id is not None
|
||||
and self._was_previous_sample_unmounted_since(mount_started_at)
|
||||
)
|
||||
|
||||
if previous_sample_unmounted:
|
||||
@@ -1428,20 +1441,7 @@ class AareDAQ:
|
||||
raise
|
||||
|
||||
def _execute_dry(self, park=True):
|
||||
self.__devs.tell.check_enable_motion()
|
||||
self.__devs.tell.wait_not_busy()
|
||||
self.__devs.tell.set_in_mount_position(True)
|
||||
|
||||
if self.sample:
|
||||
self.__devs.tell.unmount(wait=True, timeout=60.0)
|
||||
self.__cfg.current_sample = None
|
||||
|
||||
if park:
|
||||
"""set wait_cold to -1 to go to park after drying"""
|
||||
self.__devs.tell.dry(wait_cold=-1, wait=True)
|
||||
else:
|
||||
"""use default tell wait cold after drying"""
|
||||
self.__devs.tell.dry(wait=True)
|
||||
self._create_mounting_service().dry(park=park)
|
||||
|
||||
def park_and_dry(self, park = True):
|
||||
self.__cfg.try_set_busy(timeout=360)
|
||||
@@ -1452,28 +1452,6 @@ class AareDAQ:
|
||||
self.__cfg.state_busy = False
|
||||
logger.error(f"Failed to park and dry: {e}")
|
||||
raise
|
||||
|
||||
def __reset_mount_failure_counter(self, reason: str) -> None:
|
||||
previous_count = self.__cfg.get_mount_fail_count()
|
||||
if previous_count > 0:
|
||||
logger.warning(
|
||||
f"Resetting mount failure counter from {previous_count} due to: {reason}"
|
||||
)
|
||||
else:
|
||||
logger.debug(f"Mount failure counter already clear: {reason}")
|
||||
self.__cfg.record_mount_success()
|
||||
|
||||
def tell_dry(self):
|
||||
self.__cfg.try_set_busy(timeout=360)
|
||||
try:
|
||||
self.__devs.tell.check_enable_motion()
|
||||
self.__devs.tell.wait_not_busy()
|
||||
self.__devs.tell.dry(wait=True)
|
||||
self.__cfg.state_busy = False
|
||||
except Exception as e:
|
||||
self.__cfg.state_busy = False
|
||||
logger.error(f"Failed to dry TELL: {e}")
|
||||
raise
|
||||
|
||||
def tell_toggle_blower(self):
|
||||
try:
|
||||
@@ -1501,140 +1479,6 @@ class AareDAQ:
|
||||
logger.error(f"Failed to initialise detector: {e}")
|
||||
raise
|
||||
|
||||
|
||||
def __magnet_position_sensor_check(self, timeout: float = 1.0, repeat: bool = True):
|
||||
#TODO check this works, add beamstop z controls and test.
|
||||
|
||||
# logger.info("checking beamstop")
|
||||
# if self.__devs.beamstop_z.value < 24.0:
|
||||
# raise Exception("Beamstop Z below 24.0 mm - potentially unsafe with mounting")
|
||||
if self.__devs.magnet_position_sensor.value != 0:
|
||||
logger.warning("Goniometer is not in position based on magnet position sensor readout")
|
||||
for i in range(round(timeout * 10.0)):
|
||||
if self.__devs.magnet_position_sensor.value == 0:
|
||||
return
|
||||
time.sleep(0.1)
|
||||
logger.error("Goniometer didn't reach position based on magnet position sensor readout")
|
||||
raise Exception("Goniometer is not in position based on magnet position sensor readout")
|
||||
|
||||
def __mount_fail_handler(
|
||||
self,
|
||||
mount_error: bool = False,
|
||||
dry_after_fail_count: int = 3,
|
||||
end_automation_after_fail_count: int = 5
|
||||
):
|
||||
# if mount_error:
|
||||
# logger.error("Mount failed")
|
||||
# logger.debug("Mount error: ", extra={"mount_error": mount_error})
|
||||
# logger.debug("Currently fail handler disabled due to bugs..?")
|
||||
if mount_error:
|
||||
count = self.__cfg.record_mount_failure()
|
||||
if count > end_automation_after_fail_count:
|
||||
logger.error(f"Mounting continued to fail after stopping automation, contact your local contact")
|
||||
logger.debug(f"Clearing mount fail count")
|
||||
self.__cfg.record_mount_success()
|
||||
raise CriticalTellException(f"Mounting continued to fail after stopping automation, contact your local contact.")
|
||||
elif count == end_automation_after_fail_count:
|
||||
logger.error(f"Mounting failed {count} times, stopping automation")
|
||||
try:
|
||||
self._execute_dry(park=True)
|
||||
except Exception as e:
|
||||
logger.exception(f"Failed to dry after mount failure: {e}")
|
||||
raise CriticalTellException(f"Mount failed {count} times in a row, stopping automation.")
|
||||
elif count == dry_after_fail_count:
|
||||
#Dry after several fails
|
||||
logger.warning(f"Mount failed {count} times in a row; drying")
|
||||
try:
|
||||
self._execute_dry(park=False)
|
||||
except Exception as e:
|
||||
logger.exception(f"Failed to dry after mount failure: {e}")
|
||||
else:
|
||||
return
|
||||
else:
|
||||
logger.debug("Mounting succeeded, resetting mount failure counter")
|
||||
self.__cfg.record_mount_success()
|
||||
|
||||
def __mount_handler(self, target : SampleShortInfo):
|
||||
|
||||
value = self.__devs.tell.mount(address=target.tell_address(), force=True, auto_unmount=True, read_dm=False,
|
||||
wait=True, timeout=360.0)
|
||||
logger.debug(f"Mount response: {value.value}")
|
||||
|
||||
if isinstance(value, str):
|
||||
logger.error(f"Unexpected string response from Tell mount: {value}")
|
||||
raise CriticalTellException(f"Critical error in TELL mount: unexpected response '{value}'")
|
||||
|
||||
if value is None:
|
||||
logger.error("Tell mount returned no response (None)")
|
||||
raise CriticalTellException("Critical error in TELL mount: no response")
|
||||
|
||||
safe_val = getattr(value, "value", str(value))
|
||||
logger.debug(f"Mount response: {safe_val}")
|
||||
|
||||
if value == TellEventValueEnum.NO_PIN_IN_GRIPPER:
|
||||
"""No Pin in gripper is classed as a non critical mount fail
|
||||
Unless it happens multiple times in a row, in which case the mount fail handler should dry the gripper
|
||||
and if it continues stop automation as either there is several missing samples, they are stuck in the dewar
|
||||
or a problem with the gripper
|
||||
"""
|
||||
raise MountingFailed("No Pin in Gripper")
|
||||
elif value == TellEventValueEnum.PIN_IS_LOST_GRIPPER:
|
||||
"""Pin is lost gripper is classed as a non critical mount fail
|
||||
Unless it happens multiple times in a row, in which case the mount fail handler should dry the gripper
|
||||
asit may be a problem with the gripper or the type of pins. If it continues after this automation should stop.
|
||||
"""
|
||||
logger.error("Pin is lost")
|
||||
raise MountingFailed("Pin is lost")
|
||||
elif value == TellEventValueEnum.ROBOT_CLEAR_AFTER_MOUNT or value == TellEventValueEnum.DRY or value == TellEventValueEnum.COLD:
|
||||
"""Robot clear after mount, tell dry or tell cold are not fails, they are events telling the daq to allow
|
||||
automation to continue as the robot is busy but will not crash if the end station state is changed
|
||||
this allows us to save a lot of time in autoamtion"""
|
||||
logger.info(f"Robot is {getattr(value, 'value', str(value))} - freeing beamline for user")
|
||||
else:
|
||||
"""Currently there are no other fail messages from Tell"""
|
||||
# Treat any unknown/unsupported event/value as critical for now
|
||||
msg = f"Mount response not handled: {getattr(value, 'value', str(value))}"
|
||||
logger.error(msg)
|
||||
raise CriticalTellException(f"Critical error in TELL mount: {msg}")
|
||||
return
|
||||
|
||||
def __mount(self, target: SampleShortInfo | None):
|
||||
self.__devs.smargon_move_home()
|
||||
self.__devs.aerotech_pos = ABR_POS_MOUNT
|
||||
#collimator should be down!!!
|
||||
self.__magnet_position_sensor_check(timeout=360.0)
|
||||
self.__devs.tell.check_enable_motion()
|
||||
self.__devs.tell.wait_not_busy()
|
||||
self.__devs.tell.set_in_mount_position(True)
|
||||
previous_sample = self.__cfg.current_sample
|
||||
if target is None:
|
||||
if previous_sample is not None:
|
||||
logger.debug(f"Unmounting sample: {previous_sample}")
|
||||
try:
|
||||
self.__devs.tell.unmount(wait=True, timeout=60.0)
|
||||
self.__cfg.current_sample = target
|
||||
except Exception as e:
|
||||
raise UnmountingFailed(f"Failed to unmount: {e}")
|
||||
else:
|
||||
try:
|
||||
#TODO: how to differentiate between mounting and unmounting fails
|
||||
# during a typucal mount call as this is handled by Tell?
|
||||
log_msg = f"Mounting sample: {target}"
|
||||
if previous_sample is not None:
|
||||
log_msg = (f"Unmounting sample: {previous_sample} \n "
|
||||
f"and {log_msg}")
|
||||
logger.debug(log_msg)
|
||||
self.__mount_handler(target)
|
||||
self.__mount_fail_handler(mount_error=False)
|
||||
self.__cfg.current_sample = target
|
||||
except CriticalTellException as e:
|
||||
logger.error(f"Critical Tell error: {e}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"Mount failed: {e}")
|
||||
self.__mount_fail_handler(mount_error=True)
|
||||
raise
|
||||
|
||||
def recovery_unmount_sample(self) -> None:
|
||||
self.__cfg.try_set_busy(timeout=360)
|
||||
try:
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
from aare.daq.operations.mounting.models import MountingContext, MountingResult
|
||||
from aare.daq.operations.mounting.service import MountingService
|
||||
|
||||
__all__ = [
|
||||
"MountingContext",
|
||||
"MountingResult",
|
||||
"MountingService",
|
||||
]
|
||||
@@ -0,0 +1,26 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from aare.common.coordinate import AerotechCoordinate
|
||||
from aare.daq.config import BeamlineConfig
|
||||
from aare.daq.devices import BeamlineDevices
|
||||
|
||||
|
||||
@dataclass
|
||||
class MountingContext:
|
||||
cfg: BeamlineConfig
|
||||
devs: BeamlineDevices
|
||||
mount_position: AerotechCoordinate
|
||||
|
||||
|
||||
@dataclass
|
||||
class MountingResult:
|
||||
success: bool
|
||||
mounted_sample: object | None = None
|
||||
previous_sample: object | None = None
|
||||
did_unmount_previous: bool = False
|
||||
error: Exception | None = None
|
||||
comment: str | None = None
|
||||
|
||||
@property
|
||||
def is_error(self) -> bool:
|
||||
return self.error is not None
|
||||
@@ -0,0 +1,183 @@
|
||||
import time
|
||||
|
||||
from aare.common.exception_handler import (
|
||||
CriticalTellException,
|
||||
MountingFailed,
|
||||
UnmountingFailed,
|
||||
)
|
||||
from aare.devices.tell_client import TellEventValueEnum
|
||||
from aare.daq.operations.mounting.models import MountingContext, MountingResult
|
||||
|
||||
|
||||
class MountingService:
|
||||
def __init__(self, *, context: MountingContext, logger):
|
||||
self.ctx = context
|
||||
self.logger = logger
|
||||
|
||||
def reset_mount_failure_counter(self, reason: str) -> None:
|
||||
previous_count = self.ctx.cfg.get_mount_fail_count()
|
||||
if previous_count > 0:
|
||||
self.logger.warning(
|
||||
f"Resetting mount failure counter from {previous_count} due to: {reason}"
|
||||
)
|
||||
else:
|
||||
self.logger.debug(f"Mount failure counter already clear: {reason}")
|
||||
self.ctx.cfg.record_mount_success()
|
||||
|
||||
def _magnet_position_sensor_check(self, timeout: float = 1.0) -> None:
|
||||
if self.ctx.devs.magnet_position_sensor.value != 0:
|
||||
self.logger.warning(
|
||||
"Goniometer is not in position based on magnet position sensor readout"
|
||||
)
|
||||
for _ in range(round(timeout * 10.0)):
|
||||
if self.ctx.devs.magnet_position_sensor.value == 0:
|
||||
return
|
||||
time.sleep(0.1)
|
||||
|
||||
self.logger.error(
|
||||
"Goniometer didn't reach position based on magnet position sensor readout"
|
||||
)
|
||||
raise Exception("Goniometer is not in position based on magnet position sensor readout")
|
||||
|
||||
def _mount_fail_handler(
|
||||
self,
|
||||
*,
|
||||
mount_error: bool = False,
|
||||
dry_after_fail_count: int = 3,
|
||||
end_automation_after_fail_count: int = 5,
|
||||
) -> None:
|
||||
if mount_error:
|
||||
count = self.ctx.cfg.record_mount_failure()
|
||||
|
||||
if count > end_automation_after_fail_count:
|
||||
self.logger.error(
|
||||
"Mounting continued to fail after stopping automation, contact your local contact"
|
||||
)
|
||||
self.logger.debug("Clearing mount fail count")
|
||||
self.ctx.cfg.record_mount_success()
|
||||
raise CriticalTellException(
|
||||
"Mounting continued to fail after stopping automation, contact your local contact."
|
||||
)
|
||||
|
||||
if count == end_automation_after_fail_count:
|
||||
self.logger.error(f"Mounting failed {count} times, stopping automation")
|
||||
try:
|
||||
self.execute(target=None)
|
||||
self.dry(park=True)
|
||||
except Exception as e:
|
||||
self.logger.exception(f"Failed to dry after mount failure: {e}")
|
||||
raise CriticalTellException(f"Mount failed {count} times in a row, stopping automation.")
|
||||
|
||||
if count == dry_after_fail_count:
|
||||
self.logger.warning(f"Mount failed {count} times in a row; drying")
|
||||
try:
|
||||
self.dry(park=False)
|
||||
except Exception as e:
|
||||
self.logger.exception(f"Failed to dry after mount failure: {e}")
|
||||
else:
|
||||
self.logger.debug("Mounting succeeded, resetting mount failure counter")
|
||||
self.ctx.cfg.record_mount_success()
|
||||
|
||||
def _mount_handler(self, target) -> None:
|
||||
value = self.ctx.devs.tell.mount(
|
||||
address=target.tell_address(),
|
||||
force=True,
|
||||
auto_unmount=True,
|
||||
read_dm=False,
|
||||
wait=True,
|
||||
timeout=360.0,
|
||||
)
|
||||
|
||||
if isinstance(value, str):
|
||||
self.logger.error(f"Unexpected string response from Tell mount: {value}")
|
||||
raise CriticalTellException(f"Critical error in TELL mount: unexpected response '{value}'")
|
||||
|
||||
if value is None:
|
||||
self.logger.error("Tell mount returned no response (None)")
|
||||
raise CriticalTellException("Critical error in TELL mount: no response")
|
||||
|
||||
safe_val = getattr(value, "value", str(value))
|
||||
self.logger.debug(f"Mount response: {safe_val}")
|
||||
|
||||
if value == TellEventValueEnum.NO_PIN_IN_GRIPPER:
|
||||
raise MountingFailed("No Pin in Gripper")
|
||||
|
||||
if value == TellEventValueEnum.PIN_IS_LOST_GRIPPER:
|
||||
self.logger.error("Pin is lost")
|
||||
raise MountingFailed("Pin is lost")
|
||||
|
||||
if value in (
|
||||
TellEventValueEnum.ROBOT_CLEAR_AFTER_MOUNT,
|
||||
TellEventValueEnum.DRY,
|
||||
TellEventValueEnum.COLD,
|
||||
):
|
||||
self.logger.info(f"Robot is {safe_val} - freeing beamline for user")
|
||||
return
|
||||
|
||||
message = f"Mount response not handled: {safe_val}"
|
||||
self.logger.error(message)
|
||||
raise CriticalTellException(f"Critical error in TELL mount: {message}")
|
||||
|
||||
def _prepare_mount_hardware(self) -> None:
|
||||
self.ctx.devs.smargon_move_home()
|
||||
self.ctx.devs.aerotech_pos = self.ctx.mount_position
|
||||
self._magnet_position_sensor_check(timeout=360.0)
|
||||
self.ctx.devs.tell.check_enable_motion()
|
||||
self.ctx.devs.tell.wait_not_busy()
|
||||
self.ctx.devs.tell.set_in_mount_position(True)
|
||||
|
||||
def dry(self, *, park: bool) -> None:
|
||||
self.ctx.devs.tell.check_enable_motion()
|
||||
self.ctx.devs.tell.wait_not_busy()
|
||||
self.ctx.devs.tell.set_in_mount_position(True)
|
||||
|
||||
if self.ctx.cfg.current_sample:
|
||||
self.ctx.devs.tell.unmount(wait=True, timeout=60.0)
|
||||
self.ctx.cfg.current_sample = None
|
||||
|
||||
if park:
|
||||
self.ctx.devs.tell.dry(wait_cold=-1, wait=True)
|
||||
else:
|
||||
self.ctx.devs.tell.dry(wait=True)
|
||||
|
||||
def execute(self, *, target) -> MountingResult:
|
||||
try:
|
||||
self._prepare_mount_hardware()
|
||||
previous_sample = self.ctx.cfg.current_sample
|
||||
|
||||
if target is None:
|
||||
if previous_sample is not None:
|
||||
self.logger.debug(f"Unmounting sample: {previous_sample}")
|
||||
try:
|
||||
self.ctx.devs.tell.unmount(wait=True, timeout=60.0)
|
||||
self.ctx.cfg.current_sample = None
|
||||
return MountingResult(success=True)
|
||||
except Exception as e:
|
||||
raise UnmountingFailed(f"Failed to unmount: {e}") from e
|
||||
|
||||
log_msg = f"Mounting sample: {target}"
|
||||
if previous_sample is not None:
|
||||
log_msg = f"Unmounting sample: {previous_sample} \n and {log_msg}"
|
||||
self.logger.debug(log_msg)
|
||||
|
||||
self._mount_handler(target)
|
||||
self._mount_fail_handler(mount_error=False)
|
||||
self.ctx.cfg.current_sample = target
|
||||
return MountingResult(success=True)
|
||||
|
||||
except CriticalTellException as e:
|
||||
self.logger.error(f"Critical Tell error: {e}")
|
||||
return MountingResult(success=False, error=e, comment=str(e))
|
||||
|
||||
except Exception as e:
|
||||
self.logger.error(f"Mount failed: {e}")
|
||||
try:
|
||||
self._mount_fail_handler(mount_error=True)
|
||||
except Exception as fail_handler_error:
|
||||
return MountingResult(
|
||||
success=False,
|
||||
error=fail_handler_error,
|
||||
comment=str(fail_handler_error),
|
||||
)
|
||||
|
||||
return MountingResult(success=False, error=e, comment=str(e))
|
||||
Reference in new issue
Block a user