Armchair is a protocol for sending datagrams between and ot2 robot (eve) and a driver code (laptop). The default port for Armchair protocol is 50000. PACKET FIELDS Header 8B body_len: the length of the packet minus the header 1B command_type: the type of the command. 8B cid: the command id. Data Serialized python iterable args. The args are different for command_types COMMAND TYPES x00: 'init' controller->robot Description: This command tells the server to construct an Ot2Controller instance. Args: bool simulate: True is simulating bool using_temp_ctrl: True if using temperature control float temp: the temperature to keep unit at dict labware: labware information see OT2Controller.__init__ (should be a dataframe with .to_dict()) dict reagents: reagents information see excel spec DataFrame.to_dict() *note that the reagents can have multiple entries for same reagent, in which case the to dict will not work. Adding a new temporary index is required. str controller_ip: the ip address of the controller dict dry_containers: actually df with .to_dict() note: cannot be sent over pickle as is because the index has duplicates. solution is to reset the index for shipping + str index: the chemical name + float conc: the concentration once built + str loc: the location on the labware + int deck_pos: position on the deck + float required_vol: the volume of water needed to turn this into a reagent x01: 'close' controller->robot Description: This command is used to tell the robot to terminate. It should be acknowledged with a ready indicating that the robot is exiting x02: 'error' robot->controller Description: This command signifies an error that occured on the robot's side of things. Upon receipt, the Armchair will store accompanying information, update it's error state, and then raise a ConnectionError Args: Exception e: the exception raised by the robot x03: 'ready' robot->controller Description: These are effectively Acks. They're used for flow control. They are sent after a transfer, dilution, init_containers, or init Args: int cid: the command id of the command just executed x04: 'transfer' controller->robot Description: This is used to perform a transfer operation as in the excel sheet Args: str src: the chemical_name of the source well to be transfered from list> transfer_steps x05: 'init_containers' controller->robot Description: This is used to initialize container(s) for a new reaction. Args: dict product_df: (DataFrame called .to_dict()) INDEX: str chemical_name: the name of the rxn. initializes container for each row COLS: str labware: the type of labware this reaction must go in. If None, platereader will be used unless no space or too small in which case something else will be used. str container: the container this reaction must go in float max_vol: the maximum volume that will every ocupy this container. If not specified, some container will be found x06: 'sending_files' robot->controller Description: Used to initiate an ftp. Files are huge, and so they're not being sent as a payload (this may be possible, but I suspect it would be inefficient for large files) instead, after a sending_files is sent, files will be sent as a continous stream deliminated by file delimiters, (FTP_EOF in Armchair). Args: list filenames: the list of ordered filenames that are going to be sent x07: 'pause' controller-> robot: Description: Causes robot to wait for a timer to expire Args: float pause_time: the time to wait before continuing execution in seconds x08: 'stop' controller->robot: Description: tells the robot to stop and wait for user input x09: 'continue' controller->robot: GHOST_TYPE: this packet will be sent as soon as recieved without blocking Description: used to continue after a stop x0A: 'stopped' robot->controller: GHOST_TYPE: this packet will be sent as soon as recieved without blocking Description: used to signal that the robot is stopped, either from a stop command or from a callback x0B: 'loc_req' conroller->robot: GHOST_TYPE: is part of a call response so is sent immediately without waiting and is not added to inflight Description: Since the controller does not know where the robot put things, it must query those wells in order to get their locations and labware. Note if you get platereader wells you'll have to translate them back to human readable Args: list|str wellnames: the names of the wells to be queried, or the str 'all' used to request all wells. This is uselful if you don't know what exists on the robot x0C: 'loc_resp' robot->controller: GHOST_TYPE: is part of a call response so is sent immediately without waiting and is not added to inflight Description: the response to a loc_req Args: list>: 1st element is the chem name 2nd element is the well loc 3rd element is the labware deck_pos 4th element is the volume 5th element is the aspirable volumeFalse x0D: 'home' controller->robot: Description: before scanning, the robot needs to get the pipette out of the way of the reader hence we tell it to home x0E: 'make' controller->robot Description: command the robot to make a new solution from powder Args: str name: NOT THE CHEM_NAME. just the first part of the name without C float conc: the concentration of the reagent desired x0F: 'mix' controller->robot Description: command the robot to mix a set of wells Args: list>: 1st is the chem_name to be mixed 2nd is the integer mix code. 1 is mix normal, 2 is mix a lot x10: 'save' controller->robot GHOST_TYPE: part of a call response. It is expected the next pack will be a sending_files Description: commands robot to save it's data and ship it back over ftp