def get_file(self, request, pk=None): file_id = request.query_params.get('file_id', None) run = self.get_object() task = run.get_task_at_index(run.current_task) try: file_template = task.equipment_files.get(pk=file_id) except ObjectDoesNotExist: raise ValidationError({'message': 'Template does not exist'}) if run.task_in_progress and run.is_active: transfers = run.transfers.filter( run_identifier=run.task_run_identifier) serialized_transfers = ItemTransferPreviewSerializer(transfers, many=True) data_entries = DataEntry.objects.filter( task_run_identifier=run.task_run_identifier) serialized_data_entries = DataEntrySerializer(data_entries, many=True) output_data = task.data_to_output_file( file_template, serialized_data_entries.data, serialized_transfers.data) return Response(output_data) # Return a 204 as there is no task to get files for return Response(status=204)
def monitor_task(self, request, pk=None): """ Check up on a running task """ run = self.get_object() if run.task_in_progress and run.is_active: task = run.get_task_at_index(run.current_task) transfers = run.transfers.filter(run_identifier=run.task_run_identifier) serialized_transfers = ItemTransferPreviewSerializer(transfers, many=True) # Get current data for each product data_entries = DataEntry.objects.filter(task_run_identifier=run.task_run_identifier) serialized_data_entries = DataEntrySerializer(data_entries, many=True) # Get driver files # It will a file template for now # But ultimetly a driver will step in and do some processing # Will need UI/task stuff for that equipment_files = [] for ft in task.equipment_files.all(): equipment_files.append({ 'name': ft.name, 'id': ft.id, }) output_data = { 'tasks': run.tasks, 'current_task': run.current_task, 'transfers': serialized_transfers.data, 'data': serialized_data_entries.data, 'equipment_files': equipment_files, } # What stage is the task at? Talk to driver/equipment return Response(output_data) # Return a 204 as there is no task to monitor return Response(status=204)
class DetailedRunSerializer(serializers.ModelSerializer): validate_inputs = serializers.DictField(source='has_valid_inputs') products = DetailedProductSerializer(read_only=True, many=True) tasks = SimpleTaskTemplateSerializer(read_only=True, many=True, source='get_tasks') transfers = ItemTransferPreviewSerializer(read_only=True, many=True) class Meta: model = Run
def start_task(self, request, pk=None): """ Check input values and start or preview a task Takes in task data, any files and calculates if the data is valid to run the task. Pass is_check to check but not run the task. """ # Get task data from request as may have been edited to # suit current situation. task_data = json.loads(self.request.data.get('task', '{}')) if task_data.get('product_input_not_required', False): serialized_task = TaskValuesNoProductInputSerializer( data=task_data) else: serialized_task = TaskValuesSerializer(data=task_data) # Get a list of input file data to be parsed file_data = self.request.data.getlist('input_files', []) # Perform checks on the validity of the data before the # task is run, return inventory requirements. is_check = request.query_params.get('is_check', False) # Is this a repeat of a failed task # is_repeat = request.query_params.get('is_repeat', False) if serialized_task.is_valid(raise_exception=True): # Init a unit registry for later use self.ureg = UnitRegistry() run = self.get_object() task = run.get_task_at_index(run.current_task) # Get items from products product_type = serialized_task.validated_data.get( 'product_input', None) product_input_items = self._get_product_input_items(product_type) # Process task data against input_items data_items = self._generate_data_dict(product_input_items, serialized_task) # Process input files against task data data_items = self._update_data_items_from_file( file_data, data_items) # Perform calculations here! data_items = self._perform_calculations(data_items) product_item_amounts, sum_item_amounts = self._get_item_amounts( data_items, serialized_task) valid_amounts, errors, error_items = self._check_input_amounts( sum_item_amounts) # Check if a transfer already exists with given barcode/well?? transfers = self._create_item_transfers(sum_item_amounts, error_items) # Check if you can actually use the equipment if task.capable_equipment.count() > 0: equipment_name = serialized_task.validated_data[ 'equipment_choice'] try: equipment = Equipment.objects.get(name=equipment_name) except Equipment.DoesNotExist: raise serializers.ValidationError( {'message': 'Equipment does not exist!'}) else: equipment_status = equipment.status else: equipment_status = 'idle' if is_check: check_output = { 'equipment_status': equipment_status, 'errors': errors, 'requirements': [] } for t in transfers: st = ItemTransferPreviewSerializer(t) check_output['requirements'].append(st.data) return Response(check_output) else: if task.capable_equipment.count() > 0: if equipment.status != 'idle': raise serializers.ValidationError( {'message': 'Equipment is currently in use'}) equipment.status = 'active' equipment.save() run.equipment_used = equipment if not valid_amounts: raise ValidationError({'message': '\n'.join(errors)}) task_run_identifier = uuid.uuid4() # driver_output = self._do_driver_actions(data_items) # Generate DataItem for inputs for product in run.products.all(): prod_amounts = product_item_amounts[ product.product_identifier] data_items[product.product_identifier]['product_input_amounts'] = \ self._serialize_item_amounts(prod_amounts) entry = DataEntry( run=run, task_run_identifier=task_run_identifier, product=product, created_by=self.request.user, state='active', data=data_items[product.product_identifier], task=task) entry.save() # TODO: RunLabware creation # Link labeware barcode -> transfer # At this point transfers have the amount taken but are not complete # until task finished for t in transfers: t.run_identifier = task_run_identifier t.do_transfer(self.ureg) t.save() run.transfers.add(t) # Update run with new details run.task_in_progress = True run.has_started = True run.task_run_identifier = task_run_identifier run.save() return Response({'message': 'Task started successfully'})