From 8e5f1d0edc99d11915ec4d99dbcd1985300019fb Mon Sep 17 00:00:00 2001 From: Brian Cooper Date: Fri, 5 Apr 2019 16:27:38 -0400 Subject: [PATCH 1/3] feat(api): publish pause and delay commands in python and json This adds an optional message parameter to the delay function in the python apiv2. The message is published to the run log appended to the standard timing message. The json executor for apiv1 and apiv2 is capable of receiving messages for both delays and pauses. This will allow PD user's input Pause step messages to be presented in the App's run log regardless of the duration (including indefinite holds) of a pause. Closes #3308 --- api/src/opentrons/commands/commands.py | 4 +++- api/src/opentrons/protocol_api/contexts.py | 2 +- api/src/opentrons/protocol_api/execute.py | 5 +++-- api/src/opentrons/protocols/__init__.py | 7 ++++++- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/api/src/opentrons/commands/commands.py b/api/src/opentrons/commands/commands.py index dc3061f6a88..3d228ef277b 100755 --- a/api/src/opentrons/commands/commands.py +++ b/api/src/opentrons/commands/commands.py @@ -394,8 +394,10 @@ def thermocycler_deactivate(): ) -def delay(seconds, minutes): +def delay(seconds, minutes, msg): text = "Delaying for {minutes}m {seconds}s" + if msg: + text = f"{text}. {msg}" return make_command( name=command_types.DELAY, payload={ diff --git a/api/src/opentrons/protocol_api/contexts.py b/api/src/opentrons/protocol_api/contexts.py index 14531f0aeb4..f6e3f1792be 100644 --- a/api/src/opentrons/protocol_api/contexts.py +++ b/api/src/opentrons/protocol_api/contexts.py @@ -411,7 +411,7 @@ def comment(self, msg): pass @cmds.publish.both(command=cmds.delay) - def delay(self, seconds=0, minutes=0): + def delay(self, seconds=0, minutes=0, msg=None): """ Delay protocol execution for a specific amount of time. :param float seconds: A time to delay in seconds diff --git a/api/src/opentrons/protocol_api/execute.py b/api/src/opentrons/protocol_api/execute.py index f88efd3fe01..3116ff81116 100644 --- a/api/src/opentrons/protocol_api/execute.py +++ b/api/src/opentrons/protocol_api/execute.py @@ -272,13 +272,14 @@ def dispatch_json(context: ProtocolContext, # noqa(C901) if command_type == 'delay': wait = params.get('wait') + message = params.get('message') if wait is None: raise ValueError('Delay cannot be null') elif wait is True: - message = params.get('message', 'Pausing until user resumes') + message = message or 'Pausing until user resumes' context.pause(msg=message) else: - context.delay(seconds=wait) + context.delay(seconds=wait, msg=message) elif command_type == 'blowout': well = _get_well(labware, params) diff --git a/api/src/opentrons/protocols/__init__.py b/api/src/opentrons/protocols/__init__.py index 58ac67c7174..2056e75af6c 100644 --- a/api/src/opentrons/protocols/__init__.py +++ b/api/src/opentrons/protocols/__init__.py @@ -1,5 +1,6 @@ from numpy import add import time +import datetime from itertools import chain from opentrons import instruments, labware, robot @@ -175,12 +176,16 @@ def dispatch_commands(protocol_data, loaded_pipettes, loaded_labware): # noqa: if command_type == 'delay': wait = params.get('wait') + message = params.get('message') if wait is None: raise ValueError('Delay cannot be null') elif wait is True: - message = params.get('message', 'Pausing until user resumes') + message = message or 'Pausing until user resumes' robot.pause(msg=message) else: + text = f'Delaying for {datetime.timedelta(seconds=wait)}' + if message: + text = f"{text}. {message}" _sleep(wait) elif command_type == 'blowout': From e4c8cb47a8be2f27ddc73df99341fab5afccbaac Mon Sep 17 00:00:00 2001 From: Brian Cooper Date: Fri, 5 Apr 2019 17:24:18 -0400 Subject: [PATCH 2/3] fix up tests --- api/src/opentrons/commands/commands.py | 2 +- api/tests/opentrons/protocol_api/test_execute.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/opentrons/commands/commands.py b/api/src/opentrons/commands/commands.py index 3d228ef277b..3468c31e531 100755 --- a/api/src/opentrons/commands/commands.py +++ b/api/src/opentrons/commands/commands.py @@ -394,7 +394,7 @@ def thermocycler_deactivate(): ) -def delay(seconds, minutes, msg): +def delay(seconds, minutes, msg=None): text = "Delaying for {minutes}m {seconds}s" if msg: text = f"{text}. {msg}" diff --git a/api/tests/opentrons/protocol_api/test_execute.py b/api/tests/opentrons/protocol_api/test_execute.py index 9571f052bf6..a77bd977656 100644 --- a/api/tests/opentrons/protocol_api/test_execute.py +++ b/api/tests/opentrons/protocol_api/test_execute.py @@ -271,7 +271,7 @@ def test_dispatch_commands(monkeypatch, loop): cmd = [] flow_rates = [] - def mock_sleep(minutes=0, seconds=0): + def mock_sleep(minutes=0, seconds=0, msg=None): cmd.append(("sleep", seconds)) def mock_aspirate(volume, location): From dd807da1ad43741b9d4704c30ec34a8ad70c0b38 Mon Sep 17 00:00:00 2001 From: Brian Cooper Date: Wed, 10 Apr 2019 13:56:47 -0400 Subject: [PATCH 3/3] patch up from pr review --- api/src/opentrons/protocol_api/execute_v1.py | 2 +- api/src/opentrons/protocols/__init__.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api/src/opentrons/protocol_api/execute_v1.py b/api/src/opentrons/protocol_api/execute_v1.py index 068134ff21c..6000cb01a83 100644 --- a/api/src/opentrons/protocol_api/execute_v1.py +++ b/api/src/opentrons/protocol_api/execute_v1.py @@ -169,7 +169,7 @@ def dispatch_json(context: ProtocolContext, # noqa(C901) pipette_name = protocol_pipette_data.get('model') if command_type == 'delay': - wait = params.get('wait') + wait = params['wait'] message = params.get('message') if wait is None: raise ValueError('Delay cannot be null') diff --git a/api/src/opentrons/protocols/__init__.py b/api/src/opentrons/protocols/__init__.py index 2056e75af6c..c3cb8cfb5f5 100644 --- a/api/src/opentrons/protocols/__init__.py +++ b/api/src/opentrons/protocols/__init__.py @@ -186,6 +186,7 @@ def dispatch_commands(protocol_data, loaded_pipettes, loaded_labware): # noqa: text = f'Delaying for {datetime.timedelta(seconds=wait)}' if message: text = f"{text}. {message}" + robot.comment(text) _sleep(wait) elif command_type == 'blowout':