Tecan Fluent Custom Attributes

I was fumbling around with the .dll’s and I was able to spot some useful bits of information with regard to custom attributes.

I thought about teasing apart this info but figures it would be useful for determination of input variables as well.

private void AddGeneralAttributesForLabware()
    {
      this._templateList.Add("KeepForNewRun", this._factory.CreateCustomAttributeTemplate("KeepForNewRun", "Indicates that instances of last runtime workspace shall be taken for new run", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) true));
      this._templateList.Add("Static_Labware", this._factory.CreateCustomAttributeTemplate("Static_Labware", "Defines naming rule for Labware Group Editor", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) true));
      this._templateList.Add("StackerType", this._factory.CreateCustomAttributeTemplate("StackerType", "Stacker / Te-MagS plate type", true, string.Empty, (AttributeDataType) 2, string.Empty, (object) 1));
      this._templateList.Add("WasherPlateType", this._factory.CreateCustomAttributeTemplate("WasherPlateType", "Washer plate type", true, string.Empty, (AttributeDataType) 2, string.Empty, (object) 1));
    }

    private void AddPipettingAttributesForLabware()
    {
      this._templateList.Add("ClldSensitivityCalculationLabware", this._factory.CreateCustomAttributeTemplate("ClldSensitivityCalculationLabware", "Defines labware type used for cLLD sensitivity calculation", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("IsFcaLiquidWaste", this._factory.CreateCustomAttributeTemplate("IsFcaLiquidWaste", "Indicates whether labware is used as FCA liquid waste", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("IsMcaLiquidWaste", this._factory.CreateCustomAttributeTemplate("IsMcaLiquidWaste", "Indicates whether labware is used as MCA liquid waste", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("IsLiquidAspiratableIntoDevice", this._factory.CreateCustomAttributeTemplate("IsLiquidAspiratableIntoDevice", "Indicates whether the tool can be used to aspirate liquid", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("MountOffset", this._factory.CreateCustomAttributeTemplate("MountOffset", "Offset used when mounting tip; reduces Z-dimension of tip", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("SensitivityOffset", this._factory.CreateCustomAttributeTemplate("SensitivityOffset", "Offset to apply to cLLD sensitivity group when performing cLLD in labware", true, "-3;-2;-1;0;1;2;3", (AttributeDataType) 2, string.Empty, (object) 0));
      this._templateList.Add("TipCapacity", this._factory.CreateCustomAttributeTemplate("TipCapacity", "Capacity of a single tip; used for context check", false, string.Empty, (AttributeDataType) 3, "[ul]", (object) 19.0));
      this._templateList.Add("TipDimension", this._factory.CreateCustomAttributeTemplate("TipDimension", "Size of the tip in X/Y/Z", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("ToolType", this._factory.CreateCustomAttributeTemplate("ToolType", "ToolType", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("ToolIdName", this._factory.CreateCustomAttributeTemplate("ToolIdName", "ToolIdName", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("NoDiTiDetectedThreshold", this._factory.CreateCustomAttributeTemplate("NoDiTiDetectedThreshold", "No Tips Threshold", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 7.3));
      this._templateList.Add("ContinueOnFailedFCATipPickup", this._factory.CreateCustomAttributeTemplate("ContinueOnFailedFCATipPickup", "Indicates whether to automatically continue at next position if DiTi Blocked error occurs", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("PiercingDetectionHeightCompensation", this._factory.CreateCustomAttributeTemplate("PiercingDetectionHeightCompensation", "Detection height compensation offset for piercing", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
    }

    private void AddRoboticAttributesForLabware()
    {
      this._templateList.Add("HeavyObject", this._factory.CreateCustomAttributeTemplate("HeavyObject", "Indicates that a labware is a heavy object and shall be moved with limited speed", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("Grasp_location", this._factory.CreateCustomAttributeTemplate("Grasp_location", "Plate grip offset from default grasp position", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_W", this._factory.CreateCustomAttributeTemplate("Grasp_location_W", "Plate grip offset Wide", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_N", this._factory.CreateCustomAttributeTemplate("Grasp_location_N", "Plate grip offset Narrow", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Force", this._factory.CreateCustomAttributeTemplate("Force", "Force to grip plate", false, string.Empty, (AttributeDataType) 2, "[%]", (object) 50));
      this._templateList.Add("LidHandlingManual", this._factory.CreateCustomAttributeTemplate("LidHandlingManual", "If true no automatic lid handling will be done.", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) true));
      this._templateList.Add("Grip_delta", this._factory.CreateCustomAttributeTemplate("Grip_delta", "Distance added to grip distance when releasing labware or lid", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 5.0));
      this._templateList.Add("FcaGripZOffset", this._factory.CreateCustomAttributeTemplate("FcaGripZOffset", "The height the labware is gripped by FCA grippers", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
    }

    private void AddToolAttributesForLabware()
    {
      this._templateList.Add("ConnectorOffset", this._factory.CreateCustomAttributeTemplate("ConnectorOffset", "Tips: Offset between tip and adapter, Head Adapter: Offset between head and Z-Axis", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("DisplayToolName", this._factory.CreateCustomAttributeTemplate("DisplayToolName", "User-friendly name; used for Infopad, Controlbar and dropdown lists", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("DiTiTypeGroup", this._factory.CreateCustomAttributeTemplate("DiTiTypeGroup", "Group of DiTi type; used for liquid subclasses", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("DiTiToolType", this._factory.CreateCustomAttributeTemplate("DiTiToolType", "Identifier for the DiTi type", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("TipMinimumSubmergeDepth", this._factory.CreateCustomAttributeTemplate("TipMinimumSubmergeDepth", "Tip Minimum Submerge depth to prevent air aspiration", false, string.Empty, (AttributeDataType) 3, "mm", (object) 4.5));
      this._templateList.Add("FirstTipPositionOffset", this._factory.CreateCustomAttributeTemplate("FirstTipPositionOffset", "Offset between reference MCA384 tip adapter and this adapter", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("IsForMCA96TipPickup", this._factory.CreateCustomAttributeTemplate("IsForMCA96TipPickup", "Indicates whether the tool is an adapter for MCA96 tips", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("ListNumberInDropDownMenu", this._factory.CreateCustomAttributeTemplate("ListNumberInDropDownMenu", "Sorting rule in steps of ten for list of values in script command parameter 'AdapterPlate'", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 20));
      this._templateList.Add("MCA384ChannelsPerTip", this._factory.CreateCustomAttributeTemplate("MCA384ChannelsPerTip", "Factor for script commands when EVA adapter is mounted", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 1));
      this._templateList.Add("MountColumnRowWise", this._factory.CreateCustomAttributeTemplate("MountColumnRowWise", "Indicates that partial tips with this tool are only possible column- or row-wise", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("NbrOfTipsX", this._factory.CreateCustomAttributeTemplate("NbrOfTipsX", "Maximal connectable tips on an adapter in X-dimension", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 24));
      this._templateList.Add("NbrOfTipsY", this._factory.CreateCustomAttributeTemplate("NbrOfTipsY", "Maximal connectable tips on an adapter in Y-dimension", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 16));
      this._templateList.Add("OffsetConeIntoTip", this._factory.CreateCustomAttributeTemplate("OffsetConeIntoTip", "Minus offset to calculate new Z-dimension of tool after tip is mounted on the adapter", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 9.3));
      this._templateList.Add("TipSpacingX", this._factory.CreateCustomAttributeTemplate("TipSpacingX", "Spacing between single tips on tip adapter/block in X-dimension", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 4.5));
      this._templateList.Add("TipSpacingY", this._factory.CreateCustomAttributeTemplate("TipSpacingY", "Spacing between single tips on tip adapter/block in Y-dimension", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 4.5));
      this._templateList.Add("ReferenceWidth", this._factory.CreateCustomAttributeTemplate("ReferenceWidth", "Reference width of the tool", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("FingerTypeId", this._factory.CreateCustomAttributeTemplate("FingerTypeId", "Finger type number reported by memory chip of FES fingers.", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 100));
      this._templateList.Add("GripperCenterOffset", this._factory.CreateCustomAttributeTemplate("GripperCenterOffset", "Offset from rotation center to plate grip position", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("GripperZOffset", this._factory.CreateCustomAttributeTemplate("GripperZOffset", "Z-Offset from rotation center to plate grip position", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 138.3));
      this._templateList.Add("GripperSpreadOffset", this._factory.CreateCustomAttributeTemplate("GripperSpreadOffset", "Measured between the grippers", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("LeftGripperBoundingBox1Dimension", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox1Dimension", "LeftGripperBoundingBox1Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox1Offset", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox1Offset", "LeftGripperBoundingBox1Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox2Dimension", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox2Dimension", "LeftGripperBoundingBox2Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox2Offset", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox2Offset", "LeftGripperBoundingBox2Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox3Dimension", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox3Dimension", "LeftGripperBoundingBox3Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox3Offset", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox3Offset", "LeftGripperBoundingBox3Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox4Dimension", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox4Dimension", "LeftGripperBoundingBox4Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LeftGripperBoundingBox4Offset", this._factory.CreateCustomAttributeTemplate("LeftGripperBoundingBox4Offset", "LeftGripperBoundingBox4Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("GripperBoundingBoxPlaceholderOffset", this._factory.CreateCustomAttributeTemplate("GripperBoundingBoxPlaceholderOffset", "GripperBoundingBoxPlaceholderOffset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("GripperBoundingBoxPlaceholderDimension", this._factory.CreateCustomAttributeTemplate("GripperBoundingBoxPlaceholderDimension", "GripperBoundingBoxPlaceholderDimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox1Dimension", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox1Dimension", "RightGripperBoundingBox1Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox1Offset", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox1Offset", "RightGripperBoundingBox1Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox2Dimension", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox2Dimension", "RightGripperBoundingBox2Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox2Offset", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox2Offset", "RightGripperBoundingBox2Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox3Dimension", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox3Dimension", "RightGripperBoundingBox3Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox3Offset", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox3Offset", "RightGripperBoundingBox3Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox4Dimension", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox4Dimension", "RightGripperBoundingBox4Dimension", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("RightGripperBoundingBox4Offset", this._factory.CreateCustomAttributeTemplate("RightGripperBoundingBox4Offset", "RightGripperBoundingBox4Offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("MountOffsetOfFingerLeft", this._factory.CreateCustomAttributeTemplate("MountOffsetOfFingerLeft", "MountOffsetOfFingerLeft", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("MountOffsetOfFingerRight", this._factory.CreateCustomAttributeTemplate("MountOffsetOfFingerRight", "MountOffsetOfFingerRight", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
    }

    private void CreateDefaultCustomAttributesForCarrier(IDataStore dataStore)
    {
      this.AddGeneralAttributesForCarrier();
      this.AddPipettingAttributesForCarrier();
      this.AddRoboticAttributesForCarrier();
      this.AddDefaultCustomAttributesForAllTypes();
      Guid guid = new Guid("11111111-1234-aaaa-ffff-99999999999b");
      StringBuilder stringBuilder = new StringBuilder();
      foreach (KeyValuePair<string, ICustomAttributeTemplate> template in this._templateList)
        stringBuilder.Append(template.Value.SaveString());
      TypedObjectDescriptor objectDescriptor = new TypedObjectDescriptor(((IApplicationDataStore) this._appFrame).DatastoreKeys.WorktableCustomAttributeListKey, new DataObjectIdentifier("CustomAttributesCarrier"), string.Empty)
      {
        UniqueId = guid,
        Revision = "1.0"
      };
      dataStore.SaveData(objectDescriptor, new List<TypedObjectReference>(), false, stringBuilder.ToString(), objectDescriptor.Revision);
    }

    private void AddGeneralAttributesForCarrier()
    {
      this._templateList.Add("TransferStationSite", this._factory.CreateCustomAttributeTemplate("TransferStationSite", "Indicates whether the location is an transfer station site", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("BoundingBoxVisible", this._factory.CreateCustomAttributeTemplate("BoundingBoxVisible", "Indicates whether to show the bounding box(es).", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("Server", this._factory.CreateCustomAttributeTemplate("Server", "Call name of the device (internal name of driver)", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("IOState", this._factory.CreateCustomAttributeTemplate("IOState", "I/O State of associated tool driver", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("StartRack", this._factory.CreateCustomAttributeTemplate("StartRack", "Defines first position of a group of stacks for the carousel driver", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 1));
      this._templateList.Add("IsFrameElement", this._factory.CreateCustomAttributeTemplate("IsFrameElement", "Indicates whether to set carrier as part of worktable frame", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("IsGridBased", this._factory.CreateCustomAttributeTemplate("IsGridBased", "Indicates whether carrier is grid based or not", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("OpenLabwareGenerator", this._factory.CreateCustomAttributeTemplate("OpenLabwareGenerator", "Indicates whether to open labware generator", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("OpenCarrierAndSiteList", this._factory.CreateCustomAttributeTemplate("OpenCarrierAndSiteList", "Indicates whether to open labware and site list", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("PassiveStack", this._factory.CreateCustomAttributeTemplate("PassiveStack", "Indicates whether carrier is treated as a passive stack", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("WasteLocation", this._factory.CreateCustomAttributeTemplate("WasteLocation", "Indicates whether this location shall be treated as waste location", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
    }

    private void AddPipettingAttributesForCarrier() => this._templateList.Add("MaxZPositionOfHeadForGettingTips", this._factory.CreateCustomAttributeTemplate("MaxZPositionOfHeadForGettingTips", "The height which is used for the check if S-Axis can move below the active carrier clamps.", false, string.Empty, (AttributeDataType) 2, "[mm]", (object) 90.5));

    private void AddRoboticAttributesForCarrier()
    {
      this._templateList.Add("Grasp_location_min", this._factory.CreateCustomAttributeTemplate("Grasp_location_min", "Minimum Plate grip offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_max", this._factory.CreateCustomAttributeTemplate("Grasp_location_max", "Maximum Plate grip offset", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_W_min", this._factory.CreateCustomAttributeTemplate("Grasp_location_W_min", "Minimum Plate grip offset Wide", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_W_max", this._factory.CreateCustomAttributeTemplate("Grasp_location_W_max", "Maximum Plate grip offset Wide", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_N_min", this._factory.CreateCustomAttributeTemplate("Grasp_location_N_min", "Minimum Plate grip offset Narrow", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grasp_location_N_max", this._factory.CreateCustomAttributeTemplate("Grasp_location_N_max", "Maximum Plate grip offset Narrow", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("Grip_min", this._factory.CreateCustomAttributeTemplate("Grip_min", "Minimum gripper distance for labware on this carrier", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("Grip_max", this._factory.CreateCustomAttributeTemplate("Grip_max", "Maximum gripper distance for labware on this carrier", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("Grip_Narrow", this._factory.CreateCustomAttributeTemplate("Grip_Narrow", "Gripper distance Narrow for this carrier", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("Grip_Wide", this._factory.CreateCustomAttributeTemplate("Grip_Wide", "Gripper distance Wide for this carrier", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 0.0));
      this._templateList.Add("MoveableCarrier", this._factory.CreateCustomAttributeTemplate("MoveableCarrier", "Indicates whether this carrier can be moved by RGA", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) true));
      this._templateList.Add("Lid", this._factory.CreateCustomAttributeTemplate("Lid", "Specifies whether a lid is allowed on labware placed on this carrier", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("Lid_location", this._factory.CreateCustomAttributeTemplate("Lid_location", "Location to store lid", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("Lid_position", this._factory.CreateCustomAttributeTemplate("Lid_position", "Position of lid within lid location", false, string.Empty, (AttributeDataType) 4, "[mm]", (object) WorktableObjectFactory.CreateVector3D(0.0, 0.0, 0.0)));
      this._templateList.Add("LiddingStation", this._factory.CreateCustomAttributeTemplate("LiddingStation", "Carrier which is allowed to cover or uncover a lid on a labware", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("TransferStation", this._factory.CreateCustomAttributeTemplate("TransferStation", "Location to access labware for transfer from storage device", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("RobotMove", this._factory.CreateCustomAttributeTemplate("RobotMove", "On-The-Fly Tools: Used to enable/disable robot move", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("Storage", this._factory.CreateCustomAttributeTemplate("Storage", "Indicates whether lid shall remain at the location", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      this._templateList.Add("Regripstation", this._factory.CreateCustomAttributeTemplate("Regripstation", "Location to use for re-gripping", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("FesNestTouchDownOffset", this._factory.CreateCustomAttributeTemplate("FesNestTouchDownOffset", "How long should be the distance in Z to move in constant force to touch the FES nest.", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 8.0));
      this._templateList.Add("FesNestSpreadDistance", this._factory.CreateCustomAttributeTemplate("FesNestSpreadDistance", "How much spreading is needed to release the fingers (in drop fingers script command).", false, string.Empty, (AttributeDataType) 3, "[mm]", (object) 30.0));
      this._templateList.Add("OnTheFlySpeed", this._factory.CreateCustomAttributeTemplate("OnTheFlySpeed", "Maximum speed of robotic arm in % of full speed for the OnTheFly vectors.", false, string.Empty, (AttributeDataType) 2, "[%]", (object) 100));
    }

    private void AddDefaultCustomAttributesForAllTypes()
    {
      this._templateList.Add("FeatureSet", this._factory.CreateCustomAttributeTemplate("FeatureSet", "FeatureSet", false, string.Empty, (AttributeDataType) 0, string.Empty, (object) string.Empty));
      this._templateList.Add("RenderVisualChildren", this._factory.CreateCustomAttributeTemplate("RenderVisualChildren", "Indicates whether children of this object shall be rendered", false, string.Empty, (AttributeDataType) 1, string.Empty, (object) false));
      string str = ((CarrierOrLabwareProperties) 4).ToString();
      this._templateList.Add(str, this._factory.CreateCustomAttributeTemplate(str, "Preferred level for workspace delta for this type", false, string.Empty, (AttributeDataType) 2, string.Empty, (object) 0));
      this._templateList.Add("Speed", this._factory.CreateCustomAttributeTemplate("Speed", "Maximum speed of robotic arm in % of full speed", false, string.Empty, (AttributeDataType) 2, "[%]", (object) 100));
    }
7 Likes

Wow wouldn’t it be great if these descriptions were displayed as tooltips when hovering over those attributes within FC. The clarity added to things like grip_delta and gripZoffset is super useful.

Almost makes you wonder if that was the original intent and the functionality was removed to deter tinkering with settings that could easily harm the system.

2 Likes

Yeah these descriptions are useful which is why I wanted to share. I also feel like hovering over a text to display added info is a poor way to convey information outside of an IDE.

1 Like

Nice find, I wonder why this isn’t just pasted into their F1 help documentation. A lot of these are useful / insightful into the cryptic world of custom attributes, but then again documentation for users isn’t Tecan’s strong suit :roll_eyes:

1 Like

I was randomly was scrolling through this again while searching for a way to always apply a certain Z offset when using a specific labware for the RGA to avoid the bottom ridge that agilent reservoirs have. Got any suggestions @luisvillaautomata?

Also does anyone know what exactly “WorkspaceDeltaLevel” does? It seems to commonly be -1, and it’s not documented in their F1 help doc

Have you tried Grasp_location? Once selected you’ll see a vector in the shape of (0,0,0) and these represent an X, Y and Z offset. I always forget which is which so I would try something like (0,0,5) to lift 5mm from the bottom. The X and Y remain at their initial location hence 0.

1 Like

WorkspaceDeltaLevel I haven’t modified it at all. I wonder tho.

i frequently use Grasp_Location_N for moving deepwell height labware - yields a lot more gripper force if you can grip at top edge versus bottom edge of labware

be aware, applying an offset of 30mm needs to be factored into the Z heights of the vector itself - the RGA will try to move 30mm higher than all Z coordinates (e.g. out of range errors),

i try to lock uppermost Z coordinates for vectors or lower the uppermost to be maximum 170 for cleaner movements around the worktable

setting “speed” attribute is also useful - move speed is adjusted to a % of the location maximum when labware is gripped (really makes the system more robust versus typical setup where the movements run to the rev limiter)

4 Likes

Here is a list of custom attributes I got from the Tecan HelpDesk in early 2022. May be outdated.

Note: Listed Attributes are from various sources, there is actually no official written documentation for custom attributes and their actual function. The existence of a custom attribute in this list does not guarantee its implementation in the Software.

Column 1 Column 2 Column 3 Column 4 E F G
Name Description Type Valid Range Default Value Unit Section
ACCESSIBLE_FOR_LIHA Specifies whether carrier is accessible for liquid handling arms Boolean [True, False] Carrier
BoundingBoxVisible Indicates whether to show the bounding box Boolean [True, False] FALSE Carrier
Grasp_location_max Maximum value for allowed grasp position range. This Custom Attribute is used in conjunction with “Grasp_location_min” to specify a range of positions where gripping is allowed for locations. If not defined there is no limitation for the grip position Vector 0,0,0 [mm] Carrier
Grasp_location_min Minimum value for allowed grasp position range. This Custom Attribute is used in conjunction with “Grasp_location_max” to specify a range of positions where gripping is allowed for locations. If not defined there is no limitation for the grip position. Vector 0,0,0 [mm] Carrier
Grasp_location_N_max Maximum value for allowed grasp position range for narrow gripping. If not present “Grasp_location_max” is used instead. See “Grasp_location_max”. Vector 0,0,0 [mm] Carrier
Grasp_location_N_min Minimum value for allowed grasp position range for narrow gripping. If not present “Grasp_location_min” is used instead. See “Grasp_location_min”. Vector 0,0,0 [mm] Carrier
Grasp_location_W_max Maximum value for allowed grasp position range for wide gripping. If not present “Grasp_location_max” is used instead. See “Grasp_location_max”. Vector 0,0,0 [mm] Carrier
Grasp_location_W_min Minimum value for allowed grasp position range for wide gripping. If not present “Grasp_location_min” is used instead. See “Grasp_location_min”. Vector 0,0,0 [mm] Carrier
Grip_max Maximum gripper distance for Labware on this carrier Floating Point 0 [mm] Carrier
Grip_min Minimum gripper distance for Labware on this carrier Floating Point 0 [mm] Carrier
IOState I/O State of associated tool driver If value is zero the device is in off line mode / not used. Boolean [True, False] FALSE Carrier
IsFrameElement Indicates whether to set carrier as part of worktable frame Boolean [True, False] FALSE Carrier
IsGridBased Indicates whether carrier is grid based or not Boolean [True, False] FALSE Carrier
Lid If a Labware has a lid and it is moved, the Labware will be covered/uncovered depending on the existence and value of the carrier custom attribute “Lid” of the destination location. If a lid is allowed (“Lid” equals true) the Labware shall be covered with its lid while in the location. If a lid is not allowed (“Lid” is false or custom attribute is not present) the Labware shall be uncovered without lid while in the location. Boolean [True, False] Carrier
Lid_location Location where the lid is stored If a location does not specify a lid location, the base location of the Labware is used. The carrier custom attribute “Lid_location” can be used to redirect a lid to another location when a lid shall be stored there. String Carrier
Lid_position [NOT USED] Position of lid within lid location Vector 0,0,0 [mm] Carrier
LiddingStation If both source and target location specifies a Lidding Station, the one from the destination location is used. If no Lidding Station is defined, the destination location is used as Lidding Station. When moving a Labware with a lid to a location that does not allow lids, the Labware is moved to the Lidding Station. There the lid is uncovered. Then the Labware is moved to the destination location if not already there. String Carrier
OpenCarrierAndSiteList If true a list of generated Labware is display by left mouse clicking on the carrier (e.g Hotel) Boolean [True, False] FALSE Carrier
OpenLabwareGenerator If true and a Labware is dragged onto the carrier then the system shall open the Labware group editor. Boolean [True, False] FALSE Carrier
PassiveStack Indicates whether carrier is treated as a passive stack if set to one the location is used for passive stacks, i.e. when the site is occupied the next plate will be placed on top of the topmost plate. Boolean [True, False] FALSE Carrier
ReferenceOffset Carrier reference offset (offset from carrier origin to worktable pin). Carrier
RobotMove On-The-Fly Tools: Used to enable/disable robot move. If false no robot moves will be executed when accessing the On-The-Fly tool. Boolean [True, False] FALSE Carrier
Server Call name of the device (internal name of driver) String Carrier
StartSqueezePosition Squeeze position for the MCA384 related to the active carrier. Integer 138 [mm] Carrier
Storage The “Storage” attribute is used by the system if and only if the lid is moved there from a Labware, and the Labware is then moved to another location where the lid is also not allowed. In that case the lid stays in the Storage location, and not moved to the Lidding Station of the second location In any other situation the “Storage” attribute is ignored by the system Boolean [True, False] FALSE Carrier
TransferStation Location to access Labware for transfer from storage device if this custom attribute is present and set the given location will be used by robots instead of the current location. String Carrier
TransferStationSite Specifies the site within the transfer station. Integer Carrier
WasteLocation Indicates whether this location shall be treated as waste location Boolean [True, False] FALSE Carrier
DeviceID Device address String Device
Barcode Object ID String Labware
ClldSensitivityCalculationLabware Needed for the sensitivity calculation direct command. Defines the type used for the clld sensitivity calculation String Labware
Force Force to grip Labware in percent of configured force Integer [1, 100] 50 [%] Labware
Grasp_location Position where the Labware should be gripped. This is an offset from the default grasp position Vector n/a 0,0,0 [mm] Labware
Grasp_location_N Position where the Labware should be gripped when gripping narrow. This is an offset from the default grasp position. If not present “Grasp_location” is used instead. Vector n/a 0,0,0 [mm] Labware
Grasp_location_W Position where the Labware should be gripped when gripping wide. This is an offset from the default grasp position. If not present “Grasp_location” is used instead. Vector 0,0,0 [mm] Labware
Grip_delta Offset added to the grip distance before gripping and releasing the Labware. If the Labware custom attribute “Grip_delta” is not defined, then the system shall use as default 5mm Floating Point [0, +inf) 5 [mm] Labware
HeavyObject If attribute is present and set to 1 the Labware is heavy and shall be transported with lower speed / acceleration to avoid damage to the instrument. Note: Only affects the rotation Floating Point FALSE Labware
IsFcaLiquidWaste Definition of the FCA liquid wastes, as fallback the plastic waste should be used Boolean [True, False] FALSE n/a Labware
IsMcaLiquidWaste Definition of the MCA liquid wastes, as fallback, the plastic waste should be used Boolean [True, False] FALSE n/a Labware
KeepForNewRun Indicates that the Labware or tool instances of the last runtime workspace shall be taken when starting an new run Boolean [True, False] TRUE n/a Labware
LidHandlingManual If true no automatic lid handling will be done Boolean [True, False] TRUE Labware
MountOffset The offset which exists if a tip is mounted and reduces the z-dimension of the tip Floating Point n/a 0 [mm] Labware
ReferenceWidth Reference width of the tool Vector 0,0,0 [mm] Labware
RenderVisualChildren Indicates whether children of this object shall be rendered, displayed on the worktable (e.g carousel tower) Boolean [True, False] FALSE Labware
RightGripperBoundingBox1Offset RightGripperBoundingBox1Offset Vector 0,0,0 [mm] Labware
SensitivityOffset Offset which shall be applied to cLLD sensitivity group when performing cLLD in Labware of this type. No automatic robot actions or influence. Integer [-3,3] 0 n/a Labware
StackerType Plate type (numerical identifier) for Te-Stacker handling. Defines plate dimension and plate handling for stacker Integer [0, 25] 1 n/a Labware
Static_Labware Boolean to control whether new Labware gets a name with ‘’: true → name[index]. false → name_index. Boolean [True, False] TRUE n/a Labware
Volume Detected volume Floating Point Labware
WasherPlateType Plate type (numerical identifier) for Washer devices. Integer 1;2;3;4;5;6;7;8;9;10 1 Labware
WorkspaceDeltaLevel Preferred workspace delta level for this Labware As for WorkspaceDelta Level: It alters how carriers/labware can be saved. In FluentControl, there are two save points; the worktable, and the script. By default, carriers are saved on the worktable and labware is saved within the script itself. This is what allows you to have one worktable with multiple scripts, but they can all be configured slightly differently ex: one script uses 50uL DiTis and the other uses 1000uL in the same position, without having to change the software’s worktable. So this attribute allows you to change that: • -1: Default behavior. Carriers will be saved to the worktable, labware to the script. • 0: Carriers and labware will be saved to the worktable. • 1: Carriers and labware will be saved to the script Integer [-1, 0, 1] 0 n/a Labware
Speed Maximum speed of robotic arm in percentage of full speed Integer [1, 100] 100 [%[ Labware/Carrier
BARCODES Barcode of the object (carrier or Labware) and 2D barcodes of its wells. String Legacy Driver
AdapterPlateType Plate type ID for MCA adapter plates Integer Tool
ConnectorOffset Offset between DiTi and the DiTi adapter / Head adapter: Mount point between head and Z axes Vector n/a 0,0,0 [mm] Tool
DisplayToolName Descriptive name for use in the UI. Object name displayed in the Infopad and Controlbar as well as in the commands when you select the DiTi type String Tool
DiTiTypeGroup Group of DiTi type, used for liquid subclasses. It can also be the same as the already existing DiTi. At runtime FC will simply use the same LC subclass String n/a n/a n/a Tool
FeatureSet Indicates in which release is the tool allowed String Tool
FesNestSpreadDistance Custom Attribute for FES-NESTS - how much spreading is needed to release the fingers Floating Point Tool
FingerTypeId Finger type number reported by memory chip of FES fingers. Integer [1; 254] 100 Tool
FirstTipPositionOffset Offset between reference MCA384 tip adapter and this adapter Vector 0,0,0 [mm] Tool
GripperCenterOffset Offset from the rotation center to plate grip position Floating Point n/a 0 [mm] Tool
GripperSpreadOffset Measured between the grippers Floating Point n/a 0 [mm] Tool
GripperZOffset Z-Offset from rotation center to plate grip position Floating Point 138.3 [mm] Tool
InitializationOffset [NOT USED] The offset which exists during initialization between an axis with no mounted tool and mounted tool Floating Point n/a 0 [mm] Tool
IsForMCA96TipPickup Defines, which disposible TipType (MCA384 tips or MCA96 Tips) can be picked up with a MCA384 Head Adapter Boolean [True, False] FALSE n/a Tool
IsLiquidAspiratableIntoDevice Indicates whether the tool can be used to aspirate liquid Boolean [True, False] FALSE Tool
LeftGripperBoundingBox1Dimension The dimension of the first bounding box of a left gripper. Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox1Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox2Dimension Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox2Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox3Dimension The dimension of the third bounding box of a left gripper. Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox3Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox4Dimension The dimension of the fourth bounding box of a left gripper. Vector n/a 0,0,0 [mm] Tool
LeftGripperBoundingBox4Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
ListNumberInDropDownMenu Number (in steps of ten) used for sorting adapter plates in the drop down list of script commands Integer n/a 20 n/a Tool
MaxZPositionOfHeadForGettingTips The height which is used for the check if S-Axis can move below the active carrier clamps, to start squeeze with the MCA384 on an active carrier. double n/a 90.5 [mm] Tool
MCA384ChannelsPerTip Factor for script commands when EVA adapter is mounted Integer [+1] 1 n/a Tool
MountColumnRowWise Define that partial tips with this tool is only possible column- or row-wise Boolean [True, False] FALSE n/a Tool
NbrOfConnections Maximal connectable tips within an adapter Integer [+1] 24 n/a Tool
RightGripperBoundingBox1Dimension The dimension of the first bounding box of a right gripper. Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox1Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox2Dimension The dimension of the second bounding box of a right gripper. Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox2Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox3Dimension The dimension of the thirdbounding box of a right gripper. Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox3Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox4Dimension The dimension of the fourth bounding box of a right gripper. Vector n/a 0,0,0 [mm] Tool
RightGripperBoundingBox4Offset Definition of bounding box for the gripper Vector n/a 0,0,0 [mm] Tool
TipCapacity fdel Floating Point 19 [ul] Tool
TipDimension The size of the tip in X, Y, Z Vector n/a 0,0,0 [mm] Tool
TipSpacingX Spacing between single tips on the tip adapter (tip block) in X dimension Floating point n/a 4.5 [mm] Tool
TipSpacingY Spacing between single tips on the tip adapter (tip block) in Y dimension Floating Point n/a 4.5 [mm] Tool
ToolIdName Distinct descriptor. Together with ToolType has to be an unique identifier, different from already existing. String n/a n/a n/a Tool
ToolType Identifier for the DiTi type (MUST be set to LiHa.TecanDiTi for FCA tips or Mca.TecanDiTi for MCA96 tips and ESPDiTi for MCA384 tips) String n/a n/a n/a Tool
5 Likes

This is gold, bless you

2 Likes

I think they include most of these in the Fluent Control manuals now but I was hoping they had better secret one’s.

i’m just waiting for the magic “VisionX_BootUpTime” exe.config parameter so i don’t need to wait ~5 minutes for the software to open

3 Likes

This is really useful, thank you. :grinning: How does one pass a vector value from the main script? For example, there are times when I need, due to limited deck space, to grip a plate higher or lower to avoid bounding box errors in labware transfer commands. I realise I can alter the grasp_location vector attribute of a specific labware in its definition (e.g. 0,0,5 to raise it up 5mm), and have resorted (annoyingly but temporarily) to creating a copy of the labware that just has different attribute settings but this is really inconvenient and inflexible. I can’t seem to find how to set this value on-the-fly during runtime. I tried for example the following:
SetAttribute(“plate1”, grasp_location, (0,0,5))
SetAttribute(“plate1”, grasp_location, [0,0,5])
SetAttribute(“plate1”, grasp_location, “(0,0,5)”)
SetAttribute(“plate1”, grasp_location, 0,0,5)
SetAttribute(“plate1”, grasp_location(2), 5)
SetAttribute(“plate1”, grasp_location(3), 5)
and a few other things too but just can’t seem to find the right syntax. Any ideas?

This is a great question. I’ve never had to modify those variables. I guess if I had to modify a movement variable like that I would consider using execute single vector commands.

I do use the single vector commands as well sometimes but I do wish the transfer labware command simply had x/y/z offset options as it would make single vector moves unnecessary in most cases and would be safer. I had hoped that the custom attributes were the alternative and they might well prove to be, if only I could figure out how to give it a value! Interestingly I have just found that I can, without any errors being thrown, give the vector a single integer value, for example SetAttribute(“plate1”, grasp_location, 5) but have no idea whether the 5 is applied to the x, y or z, none of them or all of them. I’m going to try this out this morning on my robot and see what, if anything, it does.


In this test, I inserted an integer (5) in the value position in the expression and it sent the RGA 5 mm in the Y axis, with the X and Z being unaffected. Applying the value only to the Y part of the vector is certainly odd behaviour on the face of it but it does at least confirm that these values can be affected via this route and suggests that there may be a way to tweak the X and Z also.

1 Like

I wonder if you can get away with “0,0,5” or feeding the {D vector as a variable :thinking:

1 Like

I tried using a variable which was an array of integers (and I tried floats too) but it will only take a single indexed value from it e.g. vector_array[2] and always treats it as Y in the vector.
It doesn’t like a string either apparently.
It seems a bit odd that there doesn’t seem to be an option to set a vector as the data type in FluentControl even though it frequently uses them behind the scenes.
Nevermind, I’ll quiz someone at Tecan about it when I get a chance. Thanks for the suggestions!

Hi lipscomj - There are certain attributes that aren’t necessarily intended or expected to be modified on the fly during a run. If there are certain locations that require a specific offset or minimum offset (for example, an Agilent PlateLoc), you can set an attribute on the carrier itself, and anytime labware is transferred to that location, the labware will use that grasp location offset instead of what is set on the labware itself.

You can also set a min/max for different locations. If this is set at the carrier level, FluentControl will automatically handle the grip offset and you will not need to program it. There is a little more setup time up front, but once the min/max values are set for any limiting locations, you will not have to think about applying offsets while writing your script.

2 Likes