syntax = "proto3";

import "SiLAFramework.proto";

package sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1;

/* This feature (together with the "Labware Transfer Site Controller" feature) provides commands to trigger the sub-tasks of handing over a labware item, e.g. a microtiter plate or a tube, from one device to another in a standardized and generic way. For each labware transfer a defined sequence of commands has to be called on both involved devices to ensure the proper synchronization of all necessary transfer actions without unwanted physical interferences and to optimize the transfer performance regarding the execution time. Using the generic commands, labware transfers between any arbitrary labware handling devices can be controlled (a robot device has not necessarily to be involved). Generally, a labware transfer is executed between a source and a destination device, where one of them is the active device (executing the handover actions) and the other one is the passive device. The "Labware Transfer Manipulator Controller" feature is used to control the labware transfer on the side of the active device to hand over labware to or take over labware from a passive device, which provides the "Labware Transfer Site Controller" feature. If a device is capable to act either as the active or as the passive device of a labware transfer it must provide both features. The complete sequence of issued transfer commands on both devices is as follows: 1. Prior to the actual labware transfer a "Prepare For Output" command is sent to the source device to execute all necessary actions to be ready to release a labware item (e.g. open a tray) and simultaneously a "Prepare For Input" command is sent to the destination device to execute all necessary actions to be ready to receive a labware item (e.g. position the robotic arm near the tray of the source device). 2. When both devices have successfully finished their "Prepare For ..." command execution, the next commands are issued. 3a If the source device is the active device it will receive a "Put Labware" command to execute all necessary actions to put the labware item into the destination device. After the transfer has been finished successfully, the destination device receives a "Labware Delivered" command, that triggers all actions to be done after the labware item has been transferred (e.g. close the opened tray). 3b If the destination device is the active device it will receive a "Get Labware" command to execute all necessary actions to get the labware from the source device (e.g. gripping the labware item). After that command has been finished successfully, the source device receives a "Labware Removed" command, that triggers all actions to be done after the labware item has been transferred (e.g. close the opened tray). The command sequences for an active source or destination device have always to be as follows: - for an active source device: PrepareForOutput - PutLabware. - for an active destination device: PrepareForInput - GetLabware. If the commands issued by the client differ from the respective command sequences an "Invalid Command Sequence" error will be raised. To address the location, where a labware item can be handed over to or from other devices, every device must provide one or more uniquely named positions (handover positions) via the "Available Handover Positions" property. A robot (active device) should have at least one handover position for each device that it interacts with, whereas most passive devices will only have one handover position. In the case of a position array (e.g. a rack), the position within the array is specified via the sub-position of the handover position, passed as an index number. To address the positions within a device where the transferred labware item has to be stored at or is to be taken from (e.g. the storage positions inside an incubator), the internal position is specified. Each device must provide the number of available internal positions via the "Number Of Internal Positions" property. In the case of no multiple internal positions, this property as well as the "Internal Position" parameter value must be 1. With the "Prepare For Input" command there is also information about the labware transferred, like labware type or a unique labware identifier (e.g. a barcode). The "Intermediate Actions" parameter of the "Put Labware" and "Get Labware" commands can be used to specify commands that have to be executed while a labware item is transferred to avoid unnecessary movements, e.g. if a robot has to get a plate from a just opened tray and a lid has to be put on the plate before it will be gripped, the lid handling actions have to be included in the "Get Labware" actions. The intermediate actions have to be executed in the same order they have been specified by the "Intermediate Actions" parameter. The property "Available Intermediate Actions" returns a list of commands that can be included in a "Put Labware" or "Get Labware" command. */
service LabwareTransferManipulatorController {
  /* Put the device into a state in which it is ready to accept new labware at the specified handover position. */
  rpc PrepareForInput (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.PrepareForInput_Parameters) returns (sila2.org.silastandard.CommandConfirmation) {}
  /* Monitor the state of PrepareForInput */
  rpc PrepareForInput_Info (sila2.org.silastandard.CommandExecutionUUID) returns (stream sila2.org.silastandard.ExecutionInfo) {}
  /* Retrieve result of PrepareForInput */
  rpc PrepareForInput_Result(sila2.org.silastandard.CommandExecutionUUID) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.PrepareForInput_Responses) {}
  /* Put the device into a state in which it is ready to release the labware at the specified handover position. */
  rpc PrepareForOutput (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.PrepareForOutput_Parameters) returns (sila2.org.silastandard.CommandConfirmation) {}
  /* Monitor the state of PrepareForOutput */
  rpc PrepareForOutput_Info (sila2.org.silastandard.CommandExecutionUUID) returns (stream sila2.org.silastandard.ExecutionInfo) {}
  /* Retrieve result of PrepareForOutput */
  rpc PrepareForOutput_Result(sila2.org.silastandard.CommandExecutionUUID) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.PrepareForOutput_Responses) {}
  /* Place the currently processed labware item at the specified handover position (sent to the active source device after a "Prepare For Output" command). */
  rpc PutLabware (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.PutLabware_Parameters) returns (sila2.org.silastandard.CommandConfirmation) {}
  /* Monitor the state of PutLabware */
  rpc PutLabware_Info (sila2.org.silastandard.CommandExecutionUUID) returns (stream sila2.org.silastandard.ExecutionInfo) {}
  /* Retrieve result of PutLabware */
  rpc PutLabware_Result(sila2.org.silastandard.CommandExecutionUUID) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.PutLabware_Responses) {}
  /* Retrieve a labware item from the specified handover position (sent to the active destination device after a "Prepare For Input" command). */
  rpc GetLabware (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.GetLabware_Parameters) returns (sila2.org.silastandard.CommandConfirmation) {}
  /* Monitor the state of GetLabware */
  rpc GetLabware_Info (sila2.org.silastandard.CommandExecutionUUID) returns (stream sila2.org.silastandard.ExecutionInfo) {}
  /* Retrieve result of GetLabware */
  rpc GetLabware_Result(sila2.org.silastandard.CommandExecutionUUID) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.GetLabware_Responses) {}
  /* All handover positions of the device including the number of sub-positions. */
  rpc Get_AvailableHandoverPositions (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.Get_AvailableHandoverPositions_Parameters) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.Get_AvailableHandoverPositions_Responses) {}
  /* The number of addressable internal positions of the device. */
  rpc Get_NumberOfInternalPositions (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.Get_NumberOfInternalPositions_Parameters) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.Get_NumberOfInternalPositions_Responses) {}
  /* Returns all commands that can be executed within a "Put Labware" or "Get Labware" command execution. */
  rpc Get_AvailableIntermediateActions (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.Get_AvailableIntermediateActions_Parameters) returns (sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.Get_AvailableIntermediateActions_Responses) {}
}

/* Specifies one of the possible positions of a device where labware items can be handed over. Can contain a sub-position, e.g. for specifying a position in a rack. */
message DataType_HandoverPosition {
  message HandoverPosition_Struct {
    sila2.org.silastandard.String Position = 1;  /* The name of the handover position (must be unique within the device). */
    sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_PositionIndex SubPosition = 2;  /* The index of a sub-position within a handover position or the number of sub-positions respectively, e.g. for a rack. */
  }
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_HandoverPosition.HandoverPosition_Struct HandoverPosition = 1;  /* Specifies one of the possible positions of a device where labware items can be handed over. Can contain a sub-position, e.g. for specifying a position in a rack. */
}

/* Specifies a position via an index number, starting at 1. */
message DataType_PositionIndex {
  sila2.org.silastandard.Integer PositionIndex = 1;  /* Specifies a position via an index number, starting at 1. */
}

/* Parameters for PrepareForInput */
message PrepareForInput_Parameters {
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_HandoverPosition HandoverPosition = 1;  /* Indicates the position where the labware will be handed over. */
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_PositionIndex InternalPosition = 2;  /* Indicates the position which the labware will be stored at within the device, e.g. internal storage positions of an incubator. */
  sila2.org.silastandard.String LabwareType = 3;  /* Specifies the type of labware that will be handed over to transfer information about the labware that the device might need to handle it correctly. */
  sila2.org.silastandard.String LabwareUniqueID = 4;  /* Represents the unique identification of a labware in the controlling system. It is assigned by the system and must remain unchanged during the whole process. */
}

/* Responses of PrepareForInput */
message PrepareForInput_Responses {
}

/* Parameters for PrepareForOutput */
message PrepareForOutput_Parameters {
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_HandoverPosition HandoverPosition = 1;  /* Indicates the position where the labware will be handed over. */
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_PositionIndex InternalPosition = 2;  /* Indicates the position which the labware will be retrieved from within the device, e.g. internal storage positions of an incubator. */
}

/* Responses of PrepareForOutput */
message PrepareForOutput_Responses {
}

/* Parameters for PutLabware */
message PutLabware_Parameters {
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_HandoverPosition HandoverPosition = 1;  /* Indicates the position the labware item will be moved to. */
  repeated sila2.org.silastandard.String IntermediateActions = 2;  /* Specifies one or more commands that have to be executed within the command sequence (e.g. removing a lid). The order of execution is specified by order within the given list. Each entry must be one of the commands returned by the AvailableIntermediateCommandExecutions property. */
}

/* Responses of PutLabware */
message PutLabware_Responses {
}

/* Parameters for GetLabware */
message GetLabware_Parameters {
  sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_HandoverPosition HandoverPosition = 1;  /* Indicates the position where the labware will be retrieved from. */
  repeated sila2.org.silastandard.String IntermediateActions = 2;  /* Specifies one or more commands that have to be executed within the command sequence (e.g. removing a lid). The order of execution is specified by order within the given list. Each entry must be one of the commands returned by the AvailableIntermediateCommandExecutions property. */
}

/* Responses of GetLabware */
message GetLabware_Responses {
}

/* Parameters for AvailableHandoverPositions */
message Get_AvailableHandoverPositions_Parameters {
}

/* Responses of AvailableHandoverPositions */
message Get_AvailableHandoverPositions_Responses {
  repeated sila2.org.silastandard.instruments.labware.manipulation.labwaretransfermanipulatorcontroller.v1.DataType_HandoverPosition AvailableHandoverPositions = 1;  /* All handover positions of the device including the number of sub-positions. */
}

/* Parameters for NumberOfInternalPositions */
message Get_NumberOfInternalPositions_Parameters {
}

/* Responses of NumberOfInternalPositions */
message Get_NumberOfInternalPositions_Responses {
  sila2.org.silastandard.Integer NumberOfInternalPositions = 1;  /* The number of addressable internal positions of the device. */
}

/* Parameters for AvailableIntermediateActions */
message Get_AvailableIntermediateActions_Parameters {
}

/* Responses of AvailableIntermediateActions */
message Get_AvailableIntermediateActions_Responses {
  repeated sila2.org.silastandard.String AvailableIntermediateActions = 1;  /* Returns all commands that can be executed within a "Put Labware" or "Get Labware" command execution. */
}
