[{"data":1,"prerenderedAt":2163},["ShallowReactive",2],{"navigation":3,"\u002Fconcepts\u002Foperate\u002Ferror-handling":909,"\u002Fconcepts\u002Foperate\u002Ferror-handling-surround":2158},[4,59,188,271,445,591,760,791],{"title":5,"type":6,"device":6,"path":7,"stem":8,"children":9,"page":41},"Get Started",null,"\u002Fget-started\u002F","01.get-started",[10,15,42,47,51,55],{"title":11,"path":12,"stem":13,"type":14,"device":6},"Welcome to UniteLabs","\u002Fget-started\u002Fwelcome\u002F","01.get-started\u002F00.welcome","landing",{"title":16,"type":6,"device":6,"path":17,"stem":18,"children":19,"page":41},"Setup","\u002Fget-started\u002Fsetup\u002F","01.get-started\u002F01.setup",[20,25,29,33,37],{"title":21,"path":22,"stem":23,"type":24,"device":6},"Get access","\u002Fget-started\u002Fsetup\u002Fget-access\u002F","01.get-started\u002F01.setup\u002F00.get-access","howto",{"title":26,"path":27,"stem":28,"type":24,"device":6},"GroundControl","\u002Fget-started\u002Fsetup\u002Fgroundcontrol\u002F","01.get-started\u002F01.setup\u002F10.groundcontrol",{"title":30,"path":31,"stem":32,"type":24,"device":6},"Connect to Platform","\u002Fget-started\u002Fsetup\u002Fconnect-to-platform\u002F","01.get-started\u002F01.setup\u002F20.connect-to-platform",{"title":34,"path":35,"stem":36,"type":24,"device":6},"Set up your development machine","\u002Fget-started\u002Fsetup\u002Fdeveloper-machine\u002F","01.get-started\u002F01.setup\u002F30.developer-machine",{"title":38,"path":39,"stem":40,"type":24,"device":6},"SDK installation","\u002Fget-started\u002Fsetup\u002Fsdk-installation\u002F","01.get-started\u002F01.setup\u002F40.sdk-installation",false,{"title":43,"path":44,"stem":45,"type":46,"device":6},"Control a device","\u002Fget-started\u002Fcontrol-a-device\u002F","01.get-started\u002F02.control-a-device","tutorial",{"title":48,"path":49,"stem":50,"type":46,"device":6},"Liquid handling as code","\u002Fget-started\u002Fliquid-handling-as-code\u002F","01.get-started\u002F03.liquid-handling-as-code",{"title":52,"path":53,"stem":54,"type":46,"device":6},"Automate your workflows","\u002Fget-started\u002Fautomate-your-workflows\u002F","01.get-started\u002F04.automate-your-workflows",{"title":56,"path":57,"stem":58,"type":6,"device":6},"Self-Paced Setup Guide","\u002Fget-started\u002Fself-onboarding\u002F","01.get-started\u002F90.self-onboarding",{"title":60,"type":6,"device":6,"path":61,"stem":62,"children":63,"page":41},"How-to","\u002Fhow-to\u002F","02.how-to",[64,118,163,180],{"title":65,"type":6,"device":6,"path":66,"stem":67,"children":68,"page":41},"Connectors and devices","\u002Fhow-to\u002Fintegrate\u002F","02.how-to\u002F02.integrate",[69,102],{"title":70,"type":6,"device":6,"path":71,"stem":72,"children":73,"page":41},"Connect a device","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device",[74,78,82,86,90,94,98],{"title":75,"path":76,"stem":77,"type":24,"device":6},"Connector Configuration","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Fconnector-configuration\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F10.connector-configuration",{"title":79,"path":80,"stem":81,"type":24,"device":6},"With an executable","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Fwith-an-executable\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F20.with-an-executable",{"title":83,"path":84,"stem":85,"type":24,"device":6},"From source","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Ffrom-source\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F30.from-source",{"title":87,"path":88,"stem":89,"type":24,"device":6},"Build your own","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Fbuild-yourself\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F40.build-yourself",{"title":91,"path":92,"stem":93,"type":24,"device":6},"Headless install","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Fheadless-install\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F50.headless-install",{"title":95,"path":96,"stem":97,"type":24,"device":6},"Raspberry Pi","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Fraspberry-pi\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F55.raspberry-pi",{"title":99,"path":100,"stem":101,"type":24,"device":6},"Multi-device Networking","\u002Fhow-to\u002Fintegrate\u002Fconnect-a-device\u002Fmultiple-devices\u002F","02.how-to\u002F02.integrate\u002F20.connect-a-device\u002F60.multiple-devices",{"title":103,"type":6,"device":6,"path":104,"stem":105,"children":106,"page":41},"Use a device","\u002Fhow-to\u002Fintegrate\u002Fuse-a-device\u002F","02.how-to\u002F02.integrate\u002F30.use-a-device",[107,110,114],{"title":26,"path":108,"stem":109,"type":24,"device":6},"\u002Fhow-to\u002Fintegrate\u002Fuse-a-device\u002Fgroundcontrol\u002F","02.how-to\u002F02.integrate\u002F30.use-a-device\u002F10.groundcontrol",{"title":111,"path":112,"stem":113,"type":24,"device":6},"Platform","\u002Fhow-to\u002Fintegrate\u002Fuse-a-device\u002Fplatform\u002F","02.how-to\u002F02.integrate\u002F30.use-a-device\u002F20.platform",{"title":115,"path":116,"stem":117,"type":24,"device":6},"UniteLabs SDK & REST API","\u002Fhow-to\u002Fintegrate\u002Fuse-a-device\u002Fpython\u002F","02.how-to\u002F02.integrate\u002F30.use-a-device\u002F30.python",{"title":119,"type":6,"device":6,"path":120,"stem":121,"children":122,"page":41},"Workflows","\u002Fhow-to\u002Fautomate\u002F","02.how-to\u002F07.automate",[123,127,131,135,139,143,147,151,155,159],{"title":124,"path":125,"stem":126,"type":24,"device":6},"Deploy a workflow","\u002Fhow-to\u002Fautomate\u002Fdeploy-a-workflow\u002F","02.how-to\u002F07.automate\u002F30.deploy-a-workflow",{"title":128,"path":129,"stem":130,"type":24,"device":6},"Run a workflow","\u002Fhow-to\u002Fautomate\u002Frun-a-workflow\u002F","02.how-to\u002F07.automate\u002F35.run-a-workflow",{"title":132,"path":133,"stem":134,"type":24,"device":6},"CI\u002FCD for workflows","\u002Fhow-to\u002Fautomate\u002Fcicd-for-workflows\u002F","02.how-to\u002F07.automate\u002F40.cicd-for-workflows",{"title":136,"path":137,"stem":138,"type":24,"device":6},"HITL basics","\u002Fhow-to\u002Fautomate\u002Fbasic-hitl\u002F","02.how-to\u002F07.automate\u002F50.basic-hitl",{"title":140,"path":141,"stem":142,"type":24,"device":6},"Slack notifications and operator confirmation","\u002Fhow-to\u002Fautomate\u002Fslack-notifications\u002F","02.how-to\u002F07.automate\u002F52.slack-notifications",{"title":144,"path":145,"stem":146,"type":24,"device":6},"Typed operator inputs","\u002Fhow-to\u002Fautomate\u002Ftyped-operator-inputs\u002F","02.how-to\u002F07.automate\u002F55.typed-operator-inputs",{"title":148,"path":149,"stem":150,"type":24,"device":6},"Pause and resume a run","\u002Fhow-to\u002Fautomate\u002Fpause-and-resume\u002F","02.how-to\u002F07.automate\u002F57.pause-and-resume",{"title":152,"path":153,"stem":154,"type":24,"device":6},"Error recovery","\u002Fhow-to\u002Fautomate\u002Fbasic-error-handling\u002F","02.how-to\u002F07.automate\u002F60.basic-error-handling",{"title":156,"path":157,"stem":158,"type":24,"device":6},"Advanced error handling","\u002Fhow-to\u002Fautomate\u002Fadvanced-error-handling\u002F","02.how-to\u002F07.automate\u002F70.advanced-error-handling",{"title":160,"path":161,"stem":162,"type":24,"device":6},"Emit lineage events","\u002Fhow-to\u002Fautomate\u002Femitting-lineage-events\u002F","02.how-to\u002F07.automate\u002F90.emitting-lineage-events",{"title":164,"type":6,"device":6,"path":165,"stem":166,"children":167,"page":41},"Data","\u002Fhow-to\u002Fobserve\u002F","02.how-to\u002F08.observe",[168,172,176],{"title":169,"path":170,"stem":171,"type":24,"device":6},"File System Connector","\u002Fhow-to\u002Fobserve\u002Ffilesystem-connector\u002F","02.how-to\u002F08.observe\u002F10.filesystem-connector",{"title":173,"path":174,"stem":175,"type":24,"device":6},"Building an ETL","\u002Fhow-to\u002Fobserve\u002Fbuilding-an-etl\u002F","02.how-to\u002F08.observe\u002F20.building-an-etl",{"title":177,"path":178,"stem":179,"type":24,"device":6},"Read lineage events","\u002Fhow-to\u002Fobserve\u002Freading-lineage-events\u002F","02.how-to\u002F08.observe\u002F30.reading-lineage-events",{"title":111,"type":6,"device":6,"path":181,"stem":182,"children":183,"page":41},"\u002Fhow-to\u002Fplatform\u002F","02.how-to\u002F09.platform",[184],{"title":185,"path":186,"stem":187,"type":24,"device":6},"UniteLabs Desktop","\u002Fhow-to\u002Fplatform\u002Funitelabs-desktop\u002F","02.how-to\u002F09.platform\u002F10.unitelabs-desktop",{"title":189,"type":6,"device":6,"path":190,"stem":191,"children":192},"Technical Reference","\u002Ftechnical-reference\u002F","03.technical-reference",[193,196,201,213,226,235,244,253,262],{"title":194,"path":190,"stem":195,"type":14,"device":6},"Overview","03.technical-reference\u002Findex",{"title":197,"path":198,"stem":199,"type":200,"device":6},"REST API","\u002Ftechnical-reference\u002Frest-api\u002F","03.technical-reference\u002F01.rest-api","reference",{"title":119,"type":6,"device":6,"path":202,"stem":203,"children":204,"page":41},"\u002Ftechnical-reference\u002Fautomate\u002F","03.technical-reference\u002F07.automate",[205,209],{"title":206,"path":207,"stem":208,"type":200,"device":6},"Workflow template","\u002Ftechnical-reference\u002Fautomate\u002Fworkflow-template\u002F","03.technical-reference\u002F07.automate\u002F05.workflow-template",{"title":210,"path":211,"stem":212,"type":200,"device":6},"Workflows REST API","\u002Ftechnical-reference\u002Fautomate\u002Fworkflows-api\u002F","03.technical-reference\u002F07.automate\u002F80.workflows-api",{"title":26,"type":6,"device":6,"path":214,"stem":215,"children":216},"\u002Ftechnical-reference\u002Fgroundcontrol\u002F","03.technical-reference\u002F10.groundcontrol\u002Findex",[217,218,222],{"title":194,"path":214,"stem":215,"type":14,"device":6},{"title":219,"path":220,"stem":221,"type":200,"device":6},"Network requirements","\u002Ftechnical-reference\u002Fgroundcontrol\u002Fnetwork-requirements\u002F","03.technical-reference\u002F10.groundcontrol\u002F10.network-requirements",{"title":223,"path":224,"stem":225,"type":200,"device":6},"Changelog","\u002Ftechnical-reference\u002Fgroundcontrol\u002Fchangelog\u002F","03.technical-reference\u002F10.groundcontrol\u002F20.changelog",{"title":227,"type":6,"device":6,"path":228,"stem":229,"children":230},"UniteLabs SDK","\u002Ftechnical-reference\u002Fpython-sdk\u002F","03.technical-reference\u002F20.python-sdk\u002Findex",[231,232],{"title":194,"path":228,"stem":229,"type":14,"device":6},{"title":223,"path":233,"stem":234,"type":200,"device":6},"\u002Ftechnical-reference\u002Fpython-sdk\u002Fchangelog\u002F","03.technical-reference\u002F20.python-sdk\u002F20.changelog",{"title":236,"type":6,"device":6,"path":237,"stem":238,"children":239},"Liquid Handling SDK","\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk\u002F","03.technical-reference\u002F30.python-liquid-handling-sdk\u002Findex",[240,241],{"title":194,"path":237,"stem":238,"type":14,"device":6},{"title":223,"path":242,"stem":243,"type":200,"device":6},"\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk\u002Fchangelog\u002F","03.technical-reference\u002F30.python-liquid-handling-sdk\u002F20.changelog",{"title":245,"type":6,"device":6,"path":246,"stem":247,"children":248},"Labware","\u002Ftechnical-reference\u002Flabware\u002F","03.technical-reference\u002F40.labware\u002Findex",[249,250],{"title":194,"path":246,"stem":247,"type":14,"device":6},{"title":223,"path":251,"stem":252,"type":200,"device":6},"\u002Ftechnical-reference\u002Flabware\u002Fchangelog\u002F","03.technical-reference\u002F40.labware\u002F20.changelog",{"title":254,"type":6,"device":6,"path":255,"stem":256,"children":257},"Python Omnibus","\u002Ftechnical-reference\u002Fpython-omnibus\u002F","03.technical-reference\u002F50.python-omnibus\u002Findex",[258,259],{"title":194,"path":255,"stem":256,"type":14,"device":6},{"title":223,"path":260,"stem":261,"type":200,"device":6},"\u002Ftechnical-reference\u002Fpython-omnibus\u002Fchangelog\u002F","03.technical-reference\u002F50.python-omnibus\u002F20.changelog",{"title":263,"type":6,"device":6,"path":264,"stem":265,"children":266},"Python CDK","\u002Ftechnical-reference\u002Fpython-cdk\u002F","03.technical-reference\u002F60.python-cdk\u002Findex",[267,268],{"title":194,"path":264,"stem":265,"type":14,"device":6},{"title":223,"path":269,"stem":270,"type":200,"device":6},"\u002Ftechnical-reference\u002Fpython-cdk\u002Fchangelog\u002F","03.technical-reference\u002F60.python-cdk\u002F20.changelog",{"title":272,"type":6,"device":6,"path":273,"stem":274,"children":275,"page":41},"Concepts","\u002Fconcepts\u002F","04.concepts",[276,315,339,383,422],{"title":277,"type":6,"device":6,"path":278,"stem":279,"children":280,"page":41},"Labs as code","\u002Fconcepts\u002Flabs-as-code\u002F","04.concepts\u002F01.labs-as-code",[281,286,290],{"title":282,"path":283,"stem":284,"type":285,"device":6},"Lab as Code","\u002Fconcepts\u002Flabs-as-code\u002Fwhy-code\u002F","04.concepts\u002F01.labs-as-code\u002F00.why-code","explanation",{"title":287,"path":288,"stem":289,"type":285,"device":6},"How it works","\u002Fconcepts\u002Flabs-as-code\u002Fhow-it-works\u002F","04.concepts\u002F01.labs-as-code\u002F01.how-it-works",{"title":291,"type":6,"device":6,"path":292,"stem":293,"children":294,"page":41},"Use Cases","\u002Fconcepts\u002Flabs-as-code\u002Fuse-cases\u002F","04.concepts\u002F01.labs-as-code\u002F02.use-cases",[295,299,303,307,311],{"title":296,"path":297,"stem":298,"type":285,"device":6},"Instrument Control","\u002Fconcepts\u002Flabs-as-code\u002Fuse-cases\u002Flow-level-instrument-control\u002F","04.concepts\u002F01.labs-as-code\u002F02.use-cases\u002F10.low-level-instrument-control",{"title":300,"path":301,"stem":302,"type":285,"device":6},"Multi-device Control","\u002Fconcepts\u002Flabs-as-code\u002Fuse-cases\u002Fmulti-device-control\u002F","04.concepts\u002F01.labs-as-code\u002F02.use-cases\u002F20.multi-device-control",{"title":304,"path":305,"stem":306,"type":285,"device":6},"Workflow Orchestration","\u002Fconcepts\u002Flabs-as-code\u002Fuse-cases\u002Fworkflow-orchestration\u002F","04.concepts\u002F01.labs-as-code\u002F02.use-cases\u002F30.workflow-orchestration",{"title":308,"path":309,"stem":310,"type":285,"device":6},"Custom Apps and LIMS Integration","\u002Fconcepts\u002Flabs-as-code\u002Fuse-cases\u002Fcustom-apps-lims\u002F","04.concepts\u002F01.labs-as-code\u002F02.use-cases\u002F40.custom-apps-lims",{"title":312,"path":313,"stem":314,"type":285,"device":6},"Scale and Fleet Management","\u002Fconcepts\u002Flabs-as-code\u002Fuse-cases\u002Fscale-and-fleet\u002F","04.concepts\u002F01.labs-as-code\u002F02.use-cases\u002F50.scale-and-fleet",{"title":65,"type":6,"device":6,"path":316,"stem":317,"children":318,"page":41},"\u002Fconcepts\u002Fintegrate\u002F","04.concepts\u002F02.integrate",[319,323,327,331,335],{"title":320,"path":321,"stem":322,"type":285,"device":6},"Device","\u002Fconcepts\u002Fintegrate\u002Fdevice\u002F","04.concepts\u002F02.integrate\u002F05.device",{"title":324,"path":325,"stem":326,"type":285,"device":6},"Connector","\u002Fconcepts\u002Fintegrate\u002Fconnector\u002F","04.concepts\u002F02.integrate\u002F10.connector",{"title":328,"path":329,"stem":330,"type":285,"device":6},"Module","\u002Fconcepts\u002Fintegrate\u002Fmodule\u002F","04.concepts\u002F02.integrate\u002F20.module",{"title":332,"path":333,"stem":334,"type":285,"device":6},"Action","\u002Fconcepts\u002Fintegrate\u002Faction\u002F","04.concepts\u002F02.integrate\u002F30.action",{"title":336,"path":337,"stem":338,"type":285,"device":6},"Subscription","\u002Fconcepts\u002Fintegrate\u002Fsubscription\u002F","04.concepts\u002F02.integrate\u002F40.subscription",{"title":340,"type":6,"device":6,"path":341,"stem":342,"children":343,"page":41},"Liquid handling and robots","\u002Fconcepts\u002Foperate\u002F","04.concepts\u002F03.operate",[344,348,352,356,359,363,367,371,375,379],{"title":345,"path":346,"stem":347,"type":285,"device":6},"Liquid Handling","\u002Fconcepts\u002Foperate\u002Fliquid-handling\u002F","04.concepts\u002F03.operate\u002F10.liquid-handling",{"title":349,"path":350,"stem":351,"type":285,"device":6},"Modules","\u002Fconcepts\u002Foperate\u002Fmodules\u002F","04.concepts\u002F03.operate\u002F20.modules",{"title":353,"path":354,"stem":355,"type":285,"device":6},"Deck","\u002Fconcepts\u002Foperate\u002Fdeck\u002F","04.concepts\u002F03.operate\u002F30.deck",{"title":245,"path":357,"stem":358,"type":285,"device":6},"\u002Fconcepts\u002Foperate\u002Flabware\u002F","04.concepts\u002F03.operate\u002F40.labware",{"title":360,"path":361,"stem":362,"type":285,"device":6},"Liquids","\u002Fconcepts\u002Foperate\u002Fliquids\u002F","04.concepts\u002F03.operate\u002F50.liquids",{"title":364,"path":365,"stem":366,"type":285,"device":6},"Liquid Classes","\u002Fconcepts\u002Foperate\u002Fliquid-classes\u002F","04.concepts\u002F03.operate\u002F60.liquid-classes",{"title":368,"path":369,"stem":370,"type":285,"device":6},"Parameter Sets","\u002Fconcepts\u002Foperate\u002Fparameter-sets\u002F","04.concepts\u002F03.operate\u002F65.parameter-sets",{"title":372,"path":373,"stem":374,"type":285,"device":6},"Tips and Tip Tracking","\u002Fconcepts\u002Foperate\u002Ftips\u002F","04.concepts\u002F03.operate\u002F70.tips",{"title":376,"path":377,"stem":378,"type":285,"device":6},"Simulation","\u002Fconcepts\u002Foperate\u002Fsimulation\u002F","04.concepts\u002F03.operate\u002F80.simulation",{"title":380,"path":381,"stem":382,"type":285,"device":6},"Error Handling","\u002Fconcepts\u002Foperate\u002Ferror-handling\u002F","04.concepts\u002F03.operate\u002F90.error-handling",{"title":119,"type":6,"device":6,"path":384,"stem":385,"children":386,"page":41},"\u002Fconcepts\u002Fautomate\u002F","04.concepts\u002F07.automate",[387,391,395,399,403,407,411,415,419],{"title":388,"path":389,"stem":390,"type":285,"device":6},"Workflow","\u002Fconcepts\u002Fautomate\u002Fworkflow\u002F","04.concepts\u002F07.automate\u002F10.workflow",{"title":392,"path":393,"stem":394,"type":285,"device":6},"Phase","\u002Fconcepts\u002Fautomate\u002Fphase\u002F","04.concepts\u002F07.automate\u002F20.phase",{"title":396,"path":397,"stem":398,"type":285,"device":6},"Step","\u002Fconcepts\u002Fautomate\u002Fstep\u002F","04.concepts\u002F07.automate\u002F30.step",{"title":400,"path":401,"stem":402,"type":285,"device":6},"Runs","\u002Fconcepts\u002Fautomate\u002Fruns\u002F","04.concepts\u002F07.automate\u002F40.runs",{"title":404,"path":405,"stem":406,"type":285,"device":6},"Input","\u002Fconcepts\u002Fautomate\u002Finput\u002F","04.concepts\u002F07.automate\u002F50.input",{"title":408,"path":409,"stem":410,"type":285,"device":6},"Artifacts","\u002Fconcepts\u002Fautomate\u002Fartifacts\u002F","04.concepts\u002F07.automate\u002F60.artifacts",{"title":412,"path":413,"stem":414,"type":285,"device":6},"Logs","\u002Fconcepts\u002Fautomate\u002Flogs\u002F","04.concepts\u002F07.automate\u002F70.logs",{"title":416,"path":417,"stem":418,"type":285,"device":6},"Human in the Loop","\u002Fconcepts\u002Fautomate\u002Fhuman-in-the-loop\u002F","04.concepts\u002F07.automate\u002F80.human-in-the-loop",{"title":380,"path":420,"stem":421,"type":285,"device":6},"\u002Fconcepts\u002Fautomate\u002Ferror-handling\u002F","04.concepts\u002F07.automate\u002F90.error-handling",{"title":164,"type":6,"device":6,"path":423,"stem":424,"children":425,"page":41},"\u002Fconcepts\u002Fobserve\u002F","04.concepts\u002F08.observe",[426,429,433,437,441],{"title":194,"path":427,"stem":428,"type":14,"device":6},"\u002Fconcepts\u002Fobserve\u002Foverview\u002F","04.concepts\u002F08.observe\u002F10.overview",{"title":430,"path":431,"stem":432,"type":285,"device":6},"Object Storage","\u002Fconcepts\u002Fobserve\u002Fstorage\u002F","04.concepts\u002F08.observe\u002F10.storage",{"title":434,"path":435,"stem":436,"type":285,"device":6},"Secrets","\u002Fconcepts\u002Fobserve\u002Fsecrets\u002F","04.concepts\u002F08.observe\u002F20.secrets",{"title":438,"path":439,"stem":440,"type":285,"device":6},"Data sources","\u002Fconcepts\u002Fobserve\u002Fdata-sources\u002F","04.concepts\u002F08.observe\u002F30.data-sources",{"title":442,"path":443,"stem":444,"type":285,"device":6},"Data lineage","\u002Fconcepts\u002Fobserve\u002Fdata-lineage\u002F","04.concepts\u002F08.observe\u002F40.data-lineage",{"title":446,"type":6,"device":6,"path":447,"stem":448,"children":449,"page":41},"Devices","\u002Fdevices\u002F","05.devices",[450,453,501,514,530,567],{"title":194,"path":451,"stem":452,"type":14,"device":6},"\u002Fdevices\u002Foverview\u002F","05.devices\u002F00.overview",{"title":454,"path":455,"page":41,"children":456},"Heater-shakers","\u002Fdevices\u002Fheater-shakers\u002F",[457,478,488],{"title":458,"path":459,"stem":460,"type":200,"device":461},"QInstruments BioShake","\u002Fdevices\u002Fqinstruments-bioshake\u002F","05.devices\u002F10.qinstruments-bioshake",{"slug":462,"vendor":463,"category":464,"connector":462,"package":465,"models":466,"communication":473,"vendor_software":6,"os":474},"qinstruments-bioshake","QInstruments","Plate Shakers & Temperature Control","unitelabs-qinstruments-bioshake",[467,468,469,470,471,472],"BioShake 3000 \u002F 3000 elm \u002F 3000 elm DWP","BioShake 3000-T \u002F 3000-T elm","BioShake 5000 elm","BioShake D30 \u002F D30 elm \u002F D30-T \u002F D30-T elm","BioShake Q1 \u002F Q1 (1.2 mm) \u002F Q1 (3.0 mm) \u002F Q2","HeatPlate","serial (RS-232 over USB)",[475,476,477],"windows","linux","macos",{"title":479,"path":480,"stem":481,"type":200,"device":482},"QInstruments ColdPlate","\u002Fdevices\u002Fqinstruments-coldplate\u002F","05.devices\u002F20.qinstruments-coldplate",{"slug":483,"vendor":463,"category":464,"connector":462,"package":465,"models":484,"communication":473,"vendor_software":6,"os":487},"qinstruments-coldplate",[485,486],"ColdPlate","ColdPlate slim",[475,476,477],{"title":489,"path":490,"stem":491,"type":200,"device":492},"Inheco Thermoshake","\u002Fdevices\u002Finheco-thermoshake\u002F","05.devices\u002F30.inheco-thermoshake",{"slug":493,"vendor":494,"category":464,"connector":495,"models":496},"inheco-thermoshake","Inheco","inheco-tec-controller",[497,498,499,500],"Thermoshake AC","Thermoshake AC LC","Thermoshake Classic","Thermoshake RM",{"title":502,"path":503,"page":41,"children":504},"Incubation","\u002Fdevices\u002Fincubation\u002F",[505],{"title":506,"path":507,"stem":508,"type":200,"device":509},"Inheco SCILA","\u002Fdevices\u002Finheco-scila\u002F","05.devices\u002F40.inheco-scila",{"slug":510,"vendor":494,"category":502,"connector":510,"models":511},"inheco-scila",[512,513],"SCILA","SCILA MIX 2-gas mixing device",{"title":515,"path":516,"page":41,"children":517},"Thermal cyclers","\u002Fdevices\u002Fthermal-cyclers\u002F",[518],{"title":519,"path":520,"stem":521,"type":200,"device":522},"Inheco ODTC","\u002Fdevices\u002Finheco-odtc\u002F","05.devices\u002F50.inheco-odtc",{"slug":523,"vendor":494,"category":524,"connector":523,"models":525},"inheco-odtc","Thermal Cycler",[526,527,528,529],"ODTC 96","ODTC 96XL","ODTC 384","ODTC 384XL",{"title":531,"path":532,"page":41,"children":533},"Readers","\u002Fdevices\u002Freaders\u002F",[534,543,552],{"title":535,"path":536,"stem":537,"type":200,"device":538},"Agilent Biotek Gen5","\u002Fdevices\u002Fbiotek-gen5\u002F","05.devices\u002F60.biotek-gen5",{"slug":539,"vendor":540,"category":541,"connector":542},"biotek-gen5","Agilent","Readers & Imagers","gen5",{"title":544,"path":545,"stem":546,"type":200,"device":547},"Biotek Synergy H1","\u002Fdevices\u002Fbiotek-synergy-h1\u002F","05.devices\u002F70.biotek-synergy-h1",{"slug":548,"vendor":540,"category":541,"connector":549,"models":550},"biotek-synergy-h1","agilent-synergy-h1",[551],"BioTek Synergy H1",{"title":553,"path":554,"stem":555,"type":200,"device":556},"Tecan Infinite 200","\u002Fdevices\u002Ftecan-infinite-200\u002F","05.devices\u002F75.tecan-infinite-200",{"slug":557,"vendor":558,"category":541,"connector":557,"package":559,"models":560,"communication":564,"vendor_software":565,"os":566},"tecan-infinite-200","Tecan","unitelabs-tecan-infinite-200",[561,562,563],"Infinite F200","Infinite M200","Infinite M200 Pro","USB","i-control on Windows only, for its USB driver",[475,476,477],{"title":568,"path":569,"page":41,"children":570},"Tilt & turn","\u002Fdevices\u002Ftilt-and-turn\u002F",[571,581],{"title":572,"path":573,"stem":574,"type":200,"device":575},"QInstruments TiltStation","\u002Fdevices\u002Fqinstruments-tiltstation\u002F","05.devices\u002F80.qinstruments-tiltstation",{"slug":576,"vendor":463,"category":577,"connector":462,"package":465,"models":578,"communication":473,"vendor_software":6,"os":580},"qinstruments-tiltstation","Plate Tilting",[579],"TiltStation",[475,476,477],{"title":582,"path":583,"stem":584,"type":200,"device":585},"QInstruments TurnStation","\u002Fdevices\u002Fqinstruments-turnstation\u002F","05.devices\u002F90.qinstruments-turnstation",{"slug":586,"vendor":463,"category":587,"connector":462,"package":465,"models":588,"communication":473,"vendor_software":6,"os":590},"qinstruments-turnstation","Plate Rotating",[589],"TurnStation",[475,476,477],{"title":592,"type":6,"device":6,"path":593,"stem":594,"children":595,"page":41},"Liquid Handling and Robots","\u002Fliquid-handling-and-robots\u002F","06.liquid-handling-and-robots",[596,599,611,635,638,679,704,721,738],{"title":194,"path":597,"stem":598,"type":14,"device":6},"\u002Fliquid-handling-and-robots\u002Foverview\u002F","06.liquid-handling-and-robots\u002F00.overview",{"title":353,"type":6,"device":6,"path":600,"stem":601,"children":602,"page":41},"\u002Fliquid-handling-and-robots\u002Fdeck\u002F","06.liquid-handling-and-robots\u002F10.deck",[603,607],{"title":604,"path":605,"stem":606,"type":24,"device":6},"Building a Deck","\u002Fliquid-handling-and-robots\u002Fdeck\u002Fbuilding-a-deck\u002F","06.liquid-handling-and-robots\u002F10.deck\u002F10.building-a-deck",{"title":608,"path":609,"stem":610,"type":24,"device":6},"Save\u002FLoad a Deck","\u002Fliquid-handling-and-robots\u002Fdeck\u002Fsave-load-deck\u002F","06.liquid-handling-and-robots\u002F10.deck\u002F20.save-load-deck",{"title":612,"type":6,"device":6,"path":613,"stem":614,"children":615,"page":41},"Pipetting","\u002Fliquid-handling-and-robots\u002Fpipetting\u002F","06.liquid-handling-and-robots\u002F20.pipetting",[616,620,624,628,631],{"title":617,"path":618,"stem":619,"type":24,"device":6},"Basic Pipetting","\u002Fliquid-handling-and-robots\u002Fpipetting\u002Fbasic-pipetting\u002F","06.liquid-handling-and-robots\u002F20.pipetting\u002F10.basic-pipetting",{"title":621,"path":622,"stem":623,"type":24,"device":6},"Advanced Pipetting","\u002Fliquid-handling-and-robots\u002Fpipetting\u002Fadvanced-pipetting\u002F","06.liquid-handling-and-robots\u002F20.pipetting\u002F20.advanced-pipetting",{"title":625,"path":626,"stem":627,"type":24,"device":6},"Tip Handling","\u002Fliquid-handling-and-robots\u002Fpipetting\u002Ftip-handling\u002F","06.liquid-handling-and-robots\u002F20.pipetting\u002F30.tip-handling",{"title":364,"path":629,"stem":630,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Fpipetting\u002Fliquid-classes\u002F","06.liquid-handling-and-robots\u002F20.pipetting\u002F40.liquid-classes",{"title":632,"path":633,"stem":634,"type":24,"device":6},"Labware Transport","\u002Fliquid-handling-and-robots\u002Fpipetting\u002Flabware-transport\u002F","06.liquid-handling-and-robots\u002F20.pipetting\u002F50.labware-transport",{"title":376,"path":636,"stem":637,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Fsimulation\u002F","06.liquid-handling-and-robots\u002F30.simulation",{"title":639,"type":6,"device":6,"path":640,"stem":641,"children":642,"page":41},"Hamilton STAR","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star",[643,647,651,655,659,663,667,671,675],{"title":644,"path":645,"stem":646,"type":24,"device":6},"Positioning & Movement","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fpositioning\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F10.positioning",{"title":648,"path":649,"stem":650,"type":24,"device":6},"Gripper Module","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fcore-gripper\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F20.core-gripper",{"title":652,"path":653,"stem":654,"type":24,"device":6},"iSWAP Module","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fiswap\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F30.iswap",{"title":656,"path":657,"stem":658,"type":24,"device":6},"Using TADM","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Ftadm\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F40.tadm",{"title":660,"path":661,"stem":662,"type":24,"device":6},"Autoload Module","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fautoload\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F50.autoload",{"title":664,"path":665,"stem":666,"type":24,"device":6},"Waste Block","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fwaste-block\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F60.waste-block",{"title":668,"path":669,"stem":670,"type":24,"device":6},"Complex Mixing","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fcomplex-mixing\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F66.complex-mixing",{"title":672,"path":673,"stem":674,"type":24,"device":6},"Teaching Gripper Paddle Positions","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fgripper-positions\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F70.gripper-positions",{"title":676,"path":677,"stem":678,"type":24,"device":6},"Training a Custom Deck Position With the iSWAP","\u002Fliquid-handling-and-robots\u002Fhamilton-star\u002Fcustom-deck-position\u002F","06.liquid-handling-and-robots\u002F41.hamilton-star\u002F75.custom-deck-position",{"title":680,"type":6,"device":6,"path":681,"stem":682,"children":683,"page":41},"Hamilton Vantage","\u002Fliquid-handling-and-robots\u002Fhamilton-vantage\u002F","06.liquid-handling-and-robots\u002F42.hamilton-vantage",[684,688,692,696,700],{"title":685,"path":686,"stem":687,"type":24,"device":6},"Waste Configuration","\u002Fliquid-handling-and-robots\u002Fhamilton-vantage\u002Fwaste-configuration\u002F","06.liquid-handling-and-robots\u002F42.hamilton-vantage\u002F05.waste-configuration",{"title":689,"path":690,"stem":691,"type":24,"device":6},"Covers and Lights","\u002Fliquid-handling-and-robots\u002Fhamilton-vantage\u002Fcovers-and-lights\u002F","06.liquid-handling-and-robots\u002F42.hamilton-vantage\u002F10.covers-and-lights",{"title":693,"path":694,"stem":695,"type":24,"device":6},"IDL Module","\u002Fliquid-handling-and-robots\u002Fhamilton-vantage\u002Fidl\u002F","06.liquid-handling-and-robots\u002F42.hamilton-vantage\u002F20.idl",{"title":697,"path":698,"stem":699,"type":24,"device":6},"IPG Module","\u002Fliquid-handling-and-robots\u002Fhamilton-vantage\u002Fipg\u002F","06.liquid-handling-and-robots\u002F42.hamilton-vantage\u002F30.ipg",{"title":701,"path":702,"stem":703,"type":24,"device":6},"XL Pipettes","\u002Fliquid-handling-and-robots\u002Fhamilton-vantage\u002Fxl-channels\u002F","06.liquid-handling-and-robots\u002F42.hamilton-vantage\u002F40.xl-channels",{"title":705,"type":6,"device":6,"path":706,"stem":707,"children":708,"page":41},"Agilent Bravo","\u002Fliquid-handling-and-robots\u002Fagilent-bravo\u002F","06.liquid-handling-and-robots\u002F43.agilent-bravo",[709,712,715,718],{"title":625,"path":710,"stem":711,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Fagilent-bravo\u002Ftip-handling\u002F","06.liquid-handling-and-robots\u002F43.agilent-bravo\u002F10.tip-handling",{"title":617,"path":713,"stem":714,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Fagilent-bravo\u002Fbasic-pipetting\u002F","06.liquid-handling-and-robots\u002F43.agilent-bravo\u002F20.basic-pipetting",{"title":364,"path":716,"stem":717,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Fagilent-bravo\u002Fliquid-classes\u002F","06.liquid-handling-and-robots\u002F43.agilent-bravo\u002F25.liquid-classes",{"title":648,"path":719,"stem":720,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Fagilent-bravo\u002Fusing-the-gripper\u002F","06.liquid-handling-and-robots\u002F43.agilent-bravo\u002F30.using-the-gripper",{"title":722,"type":6,"device":6,"path":723,"stem":724,"children":725,"page":41},"Tecan FluentControl","\u002Fliquid-handling-and-robots\u002Ftecan-fluentcontrol\u002F","06.liquid-handling-and-robots\u002F44.tecan-fluentcontrol",[726,730,734],{"title":727,"path":728,"stem":729,"type":24,"device":6},"Connect & Run a Method","\u002Fliquid-handling-and-robots\u002Ftecan-fluentcontrol\u002Fconnect-and-run\u002F","06.liquid-handling-and-robots\u002F44.tecan-fluentcontrol\u002F10.connect-and-run",{"title":731,"path":732,"stem":733,"type":24,"device":6},"Sending XML Commands","\u002Fliquid-handling-and-robots\u002Ftecan-fluentcontrol\u002Fsending-xml-commands\u002F","06.liquid-handling-and-robots\u002F44.tecan-fluentcontrol\u002F20.sending-xml-commands",{"title":735,"path":736,"stem":737,"type":24,"device":6},"Full Workflow Example","\u002Fliquid-handling-and-robots\u002Ftecan-fluentcontrol\u002Ffull-workflow-example\u002F","06.liquid-handling-and-robots\u002F44.tecan-fluentcontrol\u002F30.full-workflow-example",{"title":739,"type":6,"device":6,"path":740,"stem":741,"children":742,"page":41},"Tecan Freedom EVO","\u002Fliquid-handling-and-robots\u002Ftecan-freedom-evo\u002F","06.liquid-handling-and-robots\u002F45.tecan-freedom-evo",[743,747,750,753,757],{"title":744,"path":745,"stem":746,"type":24,"device":6},"Deck & Carriers","\u002Fliquid-handling-and-robots\u002Ftecan-freedom-evo\u002Fdeck-and-carriers\u002F","06.liquid-handling-and-robots\u002F45.tecan-freedom-evo\u002F10.deck-and-carriers",{"title":625,"path":748,"stem":749,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Ftecan-freedom-evo\u002Ftip-handling\u002F","06.liquid-handling-and-robots\u002F45.tecan-freedom-evo\u002F20.tip-handling",{"title":617,"path":751,"stem":752,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Ftecan-freedom-evo\u002Fbasic-pipetting\u002F","06.liquid-handling-and-robots\u002F45.tecan-freedom-evo\u002F30.basic-pipetting",{"title":754,"path":755,"stem":756,"type":24,"device":6},"Using the Gripper (RoMa)","\u002Fliquid-handling-and-robots\u002Ftecan-freedom-evo\u002Fusing-the-gripper\u002F","06.liquid-handling-and-robots\u002F45.tecan-freedom-evo\u002F40.using-the-gripper",{"title":364,"path":758,"stem":759,"type":24,"device":6},"\u002Fliquid-handling-and-robots\u002Ftecan-freedom-evo\u002Fliquid-classes\u002F","06.liquid-handling-and-robots\u002F45.tecan-freedom-evo\u002F50.liquid-classes",{"title":245,"type":6,"device":6,"path":761,"stem":762,"children":763,"page":41},"\u002Flabware\u002F","07.labware",[764,767,771,775,779,783,787],{"title":194,"path":765,"stem":766,"type":14,"device":6},"\u002Flabware\u002Foverview\u002F","07.labware\u002F00.overview",{"title":768,"path":769,"stem":770,"type":200,"device":6},"Standard Labware","\u002Flabware\u002Fstandard-labware\u002F","07.labware\u002F10.standard-labware",{"title":772,"path":773,"stem":774,"type":200,"device":6},"Plates","\u002Flabware\u002Fplates\u002F","07.labware\u002F20.plates",{"title":776,"path":777,"stem":778,"type":200,"device":6},"Tips and Tip Racks","\u002Flabware\u002Ftips-and-racks\u002F","07.labware\u002F30.tips-and-racks",{"title":780,"path":781,"stem":782,"type":200,"device":6},"Tubes and Tube Racks","\u002Flabware\u002Ftubes-and-tube-racks\u002F","07.labware\u002F40.tubes-and-tube-racks",{"title":784,"path":785,"stem":786,"type":200,"device":6},"Troughs","\u002Flabware\u002Ftroughs\u002F","07.labware\u002F50.troughs",{"title":788,"path":789,"stem":790,"type":200,"device":6},"Carriers and Adapters","\u002Flabware\u002Fcarriers-and-adapters\u002F","07.labware\u002F60.carriers-and-adapters",{"title":792,"type":6,"device":6,"path":793,"stem":794,"children":795},"Connector Development (CDK)","\u002Fconnector-development\u002F","20.connector-development",[796,798,822,855,863,903],{"title":194,"path":793,"stem":797,"type":14,"device":6},"20.connector-development\u002Findex",{"title":799,"path":800,"stem":801,"children":802,"page":41},"Getting Started","\u002Fconnector-development\u002Fgetting-started\u002F","20.connector-development\u002F10.getting-started",[803,806,810,814,818],{"title":194,"path":804,"stem":805,"type":285,"device":6},"\u002Fconnector-development\u002Fgetting-started\u002Foverview\u002F","20.connector-development\u002F10.getting-started\u002F10.overview",{"title":807,"path":808,"stem":809,"type":24,"device":6},"What's new","\u002Fconnector-development\u002Fgetting-started\u002Fwhats-new\u002F","20.connector-development\u002F10.getting-started\u002F20.whats-new",{"title":811,"path":812,"stem":813,"type":24,"device":6},"Installation","\u002Fconnector-development\u002Fgetting-started\u002Finstallation\u002F","20.connector-development\u002F10.getting-started\u002F30.installation",{"title":815,"path":816,"stem":817,"type":24,"device":6},"Python Environment and Project Management","\u002Fconnector-development\u002Fgetting-started\u002Fpython-environments\u002F","20.connector-development\u002F10.getting-started\u002F35.python-environments",{"title":819,"path":820,"stem":821,"type":24,"device":6},"Contributing","\u002Fconnector-development\u002Fgetting-started\u002Fcontributing\u002F","20.connector-development\u002F10.getting-started\u002F40.contributing",{"title":823,"path":824,"stem":825,"children":826,"page":41},"Tutorial","\u002Fconnector-development\u002Ftutorial\u002F","20.connector-development\u002F20.tutorial",[827,831,835,839,843,847,851],{"title":828,"path":829,"stem":830,"type":46,"device":6},"Walkthrough","\u002Fconnector-development\u002Ftutorial\u002Fwalkthrough\u002F","20.connector-development\u002F20.tutorial\u002F00.walkthrough",{"title":832,"path":833,"stem":834,"type":46,"device":6},"SiLA Endpoints","\u002Fconnector-development\u002Ftutorial\u002Fsila-endpoints\u002F","20.connector-development\u002F20.tutorial\u002F10.sila-endpoints",{"title":836,"path":837,"stem":838,"type":46,"device":6},"Data Endpoints","\u002Fconnector-development\u002Ftutorial\u002Fdata-endpoints\u002F","20.connector-development\u002F20.tutorial\u002F20.data-endpoints",{"title":840,"path":841,"stem":842,"type":46,"device":6},"Controls","\u002Fconnector-development\u002Ftutorial\u002Fcontrols\u002F","20.connector-development\u002F20.tutorial\u002F30.controls",{"title":844,"path":845,"stem":846,"type":46,"device":6},"SiLA Data Types","\u002Fconnector-development\u002Ftutorial\u002Fdata-types\u002F","20.connector-development\u002F20.tutorial\u002F40.data-types",{"title":848,"path":849,"stem":850,"type":46,"device":6},"Feature","\u002Fconnector-development\u002Ftutorial\u002Fconnector-structure\u002F","20.connector-development\u002F20.tutorial\u002F70.connector-structure",{"title":852,"path":853,"stem":854,"type":46,"device":6},"Hardware Communication","\u002Fconnector-development\u002Ftutorial\u002Fhardware-communication\u002F","20.connector-development\u002F20.tutorial\u002F90.hardware-communication",{"title":272,"type":6,"device":6,"path":856,"stem":857,"children":858,"page":41},"\u002Fconnector-development\u002Fconcepts\u002F","20.connector-development\u002F30.concepts",[859],{"title":860,"path":861,"stem":862,"type":285,"device":6},"SiLA","\u002Fconnector-development\u002Fconcepts\u002Fsila\u002F","20.connector-development\u002F30.concepts\u002Fsila",{"title":864,"path":865,"stem":866,"children":867,"page":41},"Guides","\u002Fconnector-development\u002Fguides\u002F","20.connector-development\u002F40.guides",[868,872,876,880,884,888,892,895,899],{"title":869,"path":870,"stem":871,"type":24,"device":6},"Configuration","\u002Fconnector-development\u002Fguides\u002Fconfiguration\u002F","20.connector-development\u002F40.guides\u002F20.configuration",{"title":873,"path":874,"stem":875,"type":24,"device":6},"Logging","\u002Fconnector-development\u002Fguides\u002Flogging\u002F","20.connector-development\u002F40.guides\u002F21.logging",{"title":877,"path":878,"stem":879,"type":24,"device":6},"Deployment","\u002Fconnector-development\u002Fguides\u002Fdeployment\u002F","20.connector-development\u002F40.guides\u002F30.deployment",{"title":881,"path":882,"stem":883,"type":24,"device":6},"Security","\u002Fconnector-development\u002Fguides\u002Fsecurity\u002F","20.connector-development\u002F40.guides\u002F40.security",{"title":885,"path":886,"stem":887,"type":24,"device":6},"Subscriptions","\u002Fconnector-development\u002Fguides\u002Fsubscriptions\u002F","20.connector-development\u002F40.guides\u002F45.subscriptions",{"title":889,"path":890,"stem":891,"type":24,"device":6},"Execution Modes","\u002Fconnector-development\u002Fguides\u002Fexecution-modes\u002F","20.connector-development\u002F40.guides\u002F46.execution-modes",{"title":380,"path":893,"stem":894,"type":24,"device":6},"\u002Fconnector-development\u002Fguides\u002Ferror-handling\u002F","20.connector-development\u002F40.guides\u002F50.error-handling",{"title":896,"path":897,"stem":898,"type":24,"device":6},"Serial Troubleshooting","\u002Fconnector-development\u002Fguides\u002Fserial-troubleshooting\u002F","20.connector-development\u002F40.guides\u002F70.serial-troubleshooting",{"title":900,"path":901,"stem":902,"type":24,"device":6},"Testing","\u002Fconnector-development\u002Fguides\u002Ftesting\u002F","20.connector-development\u002F40.guides\u002F80.testing",{"title":904,"path":905,"stem":906,"children":907,"type":6,"device":6},"References","\u002Fconnector-development\u002Freference\u002F","20.connector-development\u002F50.reference\u002Findex",[908],{"title":904,"path":905,"stem":906,"type":200,"device":6},{"id":910,"title":380,"body":911,"description":2152,"device":6,"extension":2153,"links":6,"meta":2154,"navigation":997,"path":2155,"seo":2156,"stem":382,"type":285,"__hash__":2157},"docs\u002F04.concepts\u002F03.operate\u002F90.error-handling.md",{"type":912,"value":913,"toc":2139},"minimark",[914,923,931,939,944,956,1207,1218,1228,1232,1237,1240,1377,1381,1384,1443,1446,1450,1453,1600,1603,1607,1610,1702,1706,1729,1845,1858,1862,1865,1964,1967,2052,2059,2063,2066,2111,2115,2135],[915,916,917,918,922],"p",{},"In most software, an unhandled exception means a bad user experience. In lab automation, it can mean a plate left in an incubator overnight, a gripper holding a tube, or reagents dispensed twice. The goal of error handling here is not just to recover gracefully; it is to leave every instrument in a ",[919,920,921],"strong",{},"safe, known state"," before the script can safely continue or exits.",[915,924,925,926,930],{},"Every error handler should ask: ",[927,928,929],"em",{},"is the instrument in a safe state?"," before re-raising or continuing.",[915,932,933,934,938],{},"On this page you write error handlers yourself. When you're ready to have the workflow engine retry, pause, and resume on your behalf, see ",[935,936,937],"a",{"href":420},"Error handling"," in Automate — same idea, moved from reactive code to declared policy.",[940,941,943],"h2",{"id":942},"basic-structure","Basic structure",[915,945,946,947,951,952,955],{},"Wrap your method steps with ",[948,949,950],"code",{},"try \u002F except \u002F finally",". The ",[948,953,954],{},"finally"," block runs regardless of success or failure, so use it for cleanup that must always happen.",[957,958,963],"pre",{"className":959,"code":960,"language":961,"meta":962,"style":962},"language-python shiki shiki-themes github-light-high-contrast github-light-high-contrast github-dark-default","import logging\nfrom unitelabs.sdk import AsyncApiClient\n\nasync def run_method():\n    async with AsyncApiClient() as client:\n        incubator = await client.get_service_by_name(\"Incubator\")\n        gripper   = await client.get_service_by_name(\"Gripper\")\n\n        try:\n            await incubator.door_controller.open()\n            await gripper.arm_controller.move_plate(source=\"A1\", destination=\"B1\")\n            await incubator.door_controller.close()\n\n        except Exception as e:\n            logging.exception(\"Step failed — attempting safe state\")\n            await incubator.door_controller.close()  # always close the door\n            raise\n\n        finally:\n            await gripper.arm_controller.home()  # runs whether or not an exception occurred\n","python","",[948,964,965,978,992,999,1015,1033,1055,1072,1077,1086,1095,1125,1133,1138,1154,1165,1177,1183,1188,1196],{"__ignoreMap":962},[966,967,970,974],"span",{"class":968,"line":969},"line",1,[966,971,973],{"class":972},"sxkbv","import",[966,975,977],{"class":976},"sc-9e"," logging\n",[966,979,981,984,987,989],{"class":968,"line":980},2,[966,982,983],{"class":972},"from",[966,985,986],{"class":976}," unitelabs.sdk ",[966,988,973],{"class":972},[966,990,991],{"class":976}," AsyncApiClient\n",[966,993,995],{"class":968,"line":994},3,[966,996,998],{"emptyLinePlaceholder":997},true,"\n",[966,1000,1002,1005,1008,1012],{"class":968,"line":1001},4,[966,1003,1004],{"class":972},"async",[966,1006,1007],{"class":972}," def",[966,1009,1011],{"class":1010},"s4qFZ"," run_method",[966,1013,1014],{"class":976},"():\n",[966,1016,1018,1021,1024,1027,1030],{"class":968,"line":1017},5,[966,1019,1020],{"class":972},"    async",[966,1022,1023],{"class":972}," with",[966,1025,1026],{"class":976}," AsyncApiClient() ",[966,1028,1029],{"class":972},"as",[966,1031,1032],{"class":976}," client:\n",[966,1034,1036,1039,1042,1045,1048,1052],{"class":968,"line":1035},6,[966,1037,1038],{"class":976},"        incubator ",[966,1040,1041],{"class":972},"=",[966,1043,1044],{"class":972}," await",[966,1046,1047],{"class":976}," client.get_service_by_name(",[966,1049,1051],{"class":1050},"sCx38","\"Incubator\"",[966,1053,1054],{"class":976},")\n",[966,1056,1058,1061,1063,1065,1067,1070],{"class":968,"line":1057},7,[966,1059,1060],{"class":976},"        gripper   ",[966,1062,1041],{"class":972},[966,1064,1044],{"class":972},[966,1066,1047],{"class":976},[966,1068,1069],{"class":1050},"\"Gripper\"",[966,1071,1054],{"class":976},[966,1073,1075],{"class":968,"line":1074},8,[966,1076,998],{"emptyLinePlaceholder":997},[966,1078,1080,1083],{"class":968,"line":1079},9,[966,1081,1082],{"class":972},"        try",[966,1084,1085],{"class":976},":\n",[966,1087,1089,1092],{"class":968,"line":1088},10,[966,1090,1091],{"class":972},"            await",[966,1093,1094],{"class":976}," incubator.door_controller.open()\n",[966,1096,1098,1100,1103,1107,1109,1112,1115,1118,1120,1123],{"class":968,"line":1097},11,[966,1099,1091],{"class":972},[966,1101,1102],{"class":976}," gripper.arm_controller.move_plate(",[966,1104,1106],{"class":1105},"sNqAu","source",[966,1108,1041],{"class":972},[966,1110,1111],{"class":1050},"\"A1\"",[966,1113,1114],{"class":976},", ",[966,1116,1117],{"class":1105},"destination",[966,1119,1041],{"class":972},[966,1121,1122],{"class":1050},"\"B1\"",[966,1124,1054],{"class":976},[966,1126,1128,1130],{"class":968,"line":1127},12,[966,1129,1091],{"class":972},[966,1131,1132],{"class":976}," incubator.door_controller.close()\n",[966,1134,1136],{"class":968,"line":1135},13,[966,1137,998],{"emptyLinePlaceholder":997},[966,1139,1141,1144,1148,1151],{"class":968,"line":1140},14,[966,1142,1143],{"class":972},"        except",[966,1145,1147],{"class":1146},"sOiAX"," Exception",[966,1149,1150],{"class":972}," as",[966,1152,1153],{"class":976}," e:\n",[966,1155,1157,1160,1163],{"class":968,"line":1156},15,[966,1158,1159],{"class":976},"            logging.exception(",[966,1161,1162],{"class":1050},"\"Step failed — attempting safe state\"",[966,1164,1054],{"class":976},[966,1166,1168,1170,1173],{"class":968,"line":1167},16,[966,1169,1091],{"class":972},[966,1171,1172],{"class":976}," incubator.door_controller.close()  ",[966,1174,1176],{"class":1175},"sIsDC","# always close the door\n",[966,1178,1180],{"class":968,"line":1179},17,[966,1181,1182],{"class":972},"            raise\n",[966,1184,1186],{"class":968,"line":1185},18,[966,1187,998],{"emptyLinePlaceholder":997},[966,1189,1191,1194],{"class":968,"line":1190},19,[966,1192,1193],{"class":972},"        finally",[966,1195,1085],{"class":976},[966,1197,1199,1201,1204],{"class":968,"line":1198},20,[966,1200,1091],{"class":972},[966,1202,1203],{"class":976}," gripper.arm_controller.home()  ",[966,1205,1206],{"class":1175},"# runs whether or not an exception occurred\n",[915,1208,1209,1210,1213,1214,1217],{},"Use ",[948,1211,1212],{},"logging.exception"," rather than ",[948,1215,1216],{},"print","; it captures the full traceback and writes it to your log file.",[915,1219,1220,1221,1223,1224,1227],{},"Keep ",[948,1222,954],{}," blocks simple. If safe-state actions can themselves raise, wrap them in their own ",[948,1225,1226],{},"try \u002F except"," to prevent masking the original error.",[940,1229,1231],{"id":1230},"common-failure-patterns","Common failure patterns",[1233,1234,1236],"h3",{"id":1235},"device-timeout","Device timeout",[915,1238,1239],{},"The instrument did not respond in time. Retry once with a short delay, then raise:",[957,1241,1243],{"className":959,"code":1242,"language":961,"meta":962,"style":962},"for attempt in range(2):\n    try:\n        result = await reader.measurement.read_absorbance(well=\"A1\")\n        break\n    except TimeoutError:\n        if attempt == 1:\n            logging.error(\"Reader timed out after 2 attempts\")\n            raise\n        logging.warning(\"Reader timeout on attempt %d — retrying\", attempt + 1)\n        await asyncio.sleep(5)\n",[948,1244,1245,1268,1275,1296,1301,1311,1326,1336,1340,1364],{"__ignoreMap":962},[966,1246,1247,1250,1253,1256,1259,1262,1265],{"class":968,"line":969},[966,1248,1249],{"class":972},"for",[966,1251,1252],{"class":976}," attempt ",[966,1254,1255],{"class":972},"in",[966,1257,1258],{"class":1146}," range",[966,1260,1261],{"class":976},"(",[966,1263,1264],{"class":1146},"2",[966,1266,1267],{"class":976},"):\n",[966,1269,1270,1273],{"class":968,"line":980},[966,1271,1272],{"class":972},"    try",[966,1274,1085],{"class":976},[966,1276,1277,1280,1282,1284,1287,1290,1292,1294],{"class":968,"line":994},[966,1278,1279],{"class":976},"        result ",[966,1281,1041],{"class":972},[966,1283,1044],{"class":972},[966,1285,1286],{"class":976}," reader.measurement.read_absorbance(",[966,1288,1289],{"class":1105},"well",[966,1291,1041],{"class":972},[966,1293,1111],{"class":1050},[966,1295,1054],{"class":976},[966,1297,1298],{"class":968,"line":1001},[966,1299,1300],{"class":972},"        break\n",[966,1302,1303,1306,1309],{"class":968,"line":1017},[966,1304,1305],{"class":972},"    except",[966,1307,1308],{"class":1146}," TimeoutError",[966,1310,1085],{"class":976},[966,1312,1313,1316,1318,1321,1324],{"class":968,"line":1035},[966,1314,1315],{"class":972},"        if",[966,1317,1252],{"class":976},[966,1319,1320],{"class":972},"==",[966,1322,1323],{"class":1146}," 1",[966,1325,1085],{"class":976},[966,1327,1328,1331,1334],{"class":968,"line":1057},[966,1329,1330],{"class":976},"            logging.error(",[966,1332,1333],{"class":1050},"\"Reader timed out after 2 attempts\"",[966,1335,1054],{"class":976},[966,1337,1338],{"class":968,"line":1074},[966,1339,1182],{"class":972},[966,1341,1342,1345,1348,1351,1354,1357,1360,1362],{"class":968,"line":1079},[966,1343,1344],{"class":976},"        logging.warning(",[966,1346,1347],{"class":1050},"\"Reader timeout on attempt ",[966,1349,1350],{"class":972},"%d",[966,1352,1353],{"class":1050}," — retrying\"",[966,1355,1356],{"class":976},", attempt ",[966,1358,1359],{"class":972},"+",[966,1361,1323],{"class":1146},[966,1363,1054],{"class":976},[966,1365,1366,1369,1372,1375],{"class":968,"line":1088},[966,1367,1368],{"class":972},"        await",[966,1370,1371],{"class":976}," asyncio.sleep(",[966,1373,1374],{"class":1146},"5",[966,1376,1054],{"class":976},[1233,1378,1380],{"id":1379},"unexpected-device-state","Unexpected device state",[915,1382,1383],{},"Never silently continue when the instrument reports a state your script did not expect. Raise immediately with enough context to diagnose:",[957,1385,1387],{"className":959,"code":1386,"language":961,"meta":962,"style":962},"status = await incubator.heating.get_status()\nif not status.door_closed:\n    raise RuntimeError(\n        f\"Incubator door is open before step — expected closed. \"\n        f\"Check that no plates were left inside.\"\n    )\n",[948,1388,1389,1401,1412,1423,1431,1438],{"__ignoreMap":962},[966,1390,1391,1394,1396,1398],{"class":968,"line":969},[966,1392,1393],{"class":976},"status ",[966,1395,1041],{"class":972},[966,1397,1044],{"class":972},[966,1399,1400],{"class":976}," incubator.heating.get_status()\n",[966,1402,1403,1406,1409],{"class":968,"line":980},[966,1404,1405],{"class":972},"if",[966,1407,1408],{"class":972}," not",[966,1410,1411],{"class":976}," status.door_closed:\n",[966,1413,1414,1417,1420],{"class":968,"line":994},[966,1415,1416],{"class":972},"    raise",[966,1418,1419],{"class":1146}," RuntimeError",[966,1421,1422],{"class":976},"(\n",[966,1424,1425,1428],{"class":968,"line":1001},[966,1426,1427],{"class":972},"        f",[966,1429,1430],{"class":1050},"\"Incubator door is open before step — expected closed. \"\n",[966,1432,1433,1435],{"class":968,"line":1017},[966,1434,1427],{"class":972},[966,1436,1437],{"class":1050},"\"Check that no plates were left inside.\"\n",[966,1439,1440],{"class":968,"line":1035},[966,1441,1442],{"class":976},"    )\n",[915,1444,1445],{},"Silence here turns a detectable misconfiguration into an unexplained result.",[1233,1447,1449],{"id":1448},"partial-completion","Partial completion",[915,1451,1452],{},"If the method fails halfway through, write whatever results you have before re-raising. Data from completed samples is valuable even when the run did not finish:",[957,1454,1456],{"className":959,"code":1455,"language":961,"meta":962,"style":962},"results = []\ntry:\n    for sample in samples:\n        measurement = await reader.measurement.read_absorbance(well=sample[\"position\"])\n        results.append({\"id\": sample[\"id\"], \"absorbance\": measurement.value})\nexcept Exception:\n    logging.error(\"Run aborted — saving %d partial results\", len(results))\n    with open(\"results_partial.json\", \"w\") as f:\n        json.dump(results, f)\n    raise\n",[948,1457,1458,1468,1475,1488,1512,1534,1543,1564,1590,1595],{"__ignoreMap":962},[966,1459,1460,1463,1465],{"class":968,"line":969},[966,1461,1462],{"class":976},"results ",[966,1464,1041],{"class":972},[966,1466,1467],{"class":976}," []\n",[966,1469,1470,1473],{"class":968,"line":980},[966,1471,1472],{"class":972},"try",[966,1474,1085],{"class":976},[966,1476,1477,1480,1483,1485],{"class":968,"line":994},[966,1478,1479],{"class":972},"    for",[966,1481,1482],{"class":976}," sample ",[966,1484,1255],{"class":972},[966,1486,1487],{"class":976}," samples:\n",[966,1489,1490,1493,1495,1497,1499,1501,1503,1506,1509],{"class":968,"line":1001},[966,1491,1492],{"class":976},"        measurement ",[966,1494,1041],{"class":972},[966,1496,1044],{"class":972},[966,1498,1286],{"class":976},[966,1500,1289],{"class":1105},[966,1502,1041],{"class":972},[966,1504,1505],{"class":976},"sample[",[966,1507,1508],{"class":1050},"\"position\"",[966,1510,1511],{"class":976},"])\n",[966,1513,1514,1517,1520,1523,1525,1528,1531],{"class":968,"line":1017},[966,1515,1516],{"class":976},"        results.append({",[966,1518,1519],{"class":1050},"\"id\"",[966,1521,1522],{"class":976},": sample[",[966,1524,1519],{"class":1050},[966,1526,1527],{"class":976},"], ",[966,1529,1530],{"class":1050},"\"absorbance\"",[966,1532,1533],{"class":976},": measurement.value})\n",[966,1535,1536,1539,1541],{"class":968,"line":1035},[966,1537,1538],{"class":972},"except",[966,1540,1147],{"class":1146},[966,1542,1085],{"class":976},[966,1544,1545,1548,1551,1553,1556,1558,1561],{"class":968,"line":1057},[966,1546,1547],{"class":976},"    logging.error(",[966,1549,1550],{"class":1050},"\"Run aborted — saving ",[966,1552,1350],{"class":972},[966,1554,1555],{"class":1050}," partial results\"",[966,1557,1114],{"class":976},[966,1559,1560],{"class":1146},"len",[966,1562,1563],{"class":976},"(results))\n",[966,1565,1566,1569,1572,1574,1577,1579,1582,1585,1587],{"class":968,"line":1074},[966,1567,1568],{"class":972},"    with",[966,1570,1571],{"class":1146}," open",[966,1573,1261],{"class":976},[966,1575,1576],{"class":1050},"\"results_partial.json\"",[966,1578,1114],{"class":976},[966,1580,1581],{"class":1050},"\"w\"",[966,1583,1584],{"class":976},") ",[966,1586,1029],{"class":972},[966,1588,1589],{"class":976}," f:\n",[966,1591,1592],{"class":968,"line":1079},[966,1593,1594],{"class":976},"        json.dump(results, f)\n",[966,1596,1597],{"class":968,"line":1088},[966,1598,1599],{"class":972},"    raise\n",[915,1601,1602],{},"Writing results incrementally during the loop makes this automatic. Your method accumulates partial data as it runs rather than buffering everything until the end.",[1233,1604,1606],{"id":1605},"connection-loss","Connection loss",[915,1608,1609],{},"Catch connection errors separately from device-logic errors, since the recovery is different:",[957,1611,1613],{"className":959,"code":1612,"language":961,"meta":962,"style":962},"try:\n    await thermocycler.temperature_controller.set_target_temperature(target_temperature=37)\nexcept ConnectionError as e:\n    logging.error(\"Lost connection to thermocycler: %s\", e)\n    # Connectors handle reconnection to the instrument automatically\n    # Automatic retries with a delay or exponential backoff may be sufficient\n    raise\nexcept Exception:\n    logging.exception(\"Thermocycler command failed\")\n    raise\n",[948,1614,1615,1621,1639,1650,1666,1671,1676,1680,1688,1698],{"__ignoreMap":962},[966,1616,1617,1619],{"class":968,"line":969},[966,1618,1472],{"class":972},[966,1620,1085],{"class":976},[966,1622,1623,1626,1629,1632,1634,1637],{"class":968,"line":980},[966,1624,1625],{"class":972},"    await",[966,1627,1628],{"class":976}," thermocycler.temperature_controller.set_target_temperature(",[966,1630,1631],{"class":1105},"target_temperature",[966,1633,1041],{"class":972},[966,1635,1636],{"class":1146},"37",[966,1638,1054],{"class":976},[966,1640,1641,1643,1646,1648],{"class":968,"line":994},[966,1642,1538],{"class":972},[966,1644,1645],{"class":1146}," ConnectionError",[966,1647,1150],{"class":972},[966,1649,1153],{"class":976},[966,1651,1652,1654,1657,1660,1663],{"class":968,"line":1001},[966,1653,1547],{"class":976},[966,1655,1656],{"class":1050},"\"Lost connection to thermocycler: ",[966,1658,1659],{"class":972},"%s",[966,1661,1662],{"class":1050},"\"",[966,1664,1665],{"class":976},", e)\n",[966,1667,1668],{"class":968,"line":1017},[966,1669,1670],{"class":1175},"    # Connectors handle reconnection to the instrument automatically\n",[966,1672,1673],{"class":968,"line":1035},[966,1674,1675],{"class":1175},"    # Automatic retries with a delay or exponential backoff may be sufficient\n",[966,1677,1678],{"class":968,"line":1057},[966,1679,1599],{"class":972},[966,1681,1682,1684,1686],{"class":968,"line":1074},[966,1683,1538],{"class":972},[966,1685,1147],{"class":1146},[966,1687,1085],{"class":976},[966,1689,1690,1693,1696],{"class":968,"line":1079},[966,1691,1692],{"class":976},"    logging.exception(",[966,1694,1695],{"class":1050},"\"Thermocycler command failed\"",[966,1697,1054],{"class":976},[966,1699,1700],{"class":968,"line":1088},[966,1701,1599],{"class":972},[940,1703,1705],{"id":1704},"marking-labware-as-errored","Marking labware as errored",[915,1707,1708,1709,1712,1713,1716,1717,1720,1721,1724,1725,1728],{},"After a failed tip pickup or transport step you often cannot trust what is physically in a spot — a tube may have been dropped, a tip half-mounted. Since labware 0.29.0, you can record that uncertainty on the labware itself instead of guessing later. ",[948,1710,1711],{},"Spot.mark_errored()"," (available on ",[948,1714,1715],{},"TipSpot"," and ",[948,1718,1719],{},"TubeSpot",") clears whatever the spot held and replaces it with an ",[948,1722,1723],{},"Unknown"," placeholder, and ",[948,1726,1727],{},"spot.errored"," reports the state:",[957,1730,1732],{"className":959,"code":1731,"language":961,"meta":962,"style":962},"from unitelabs.labware import Unknown\n\nspot = tip_rack[\"A1\"]\n\ntry:\n    await hamilton.pipettes.pick_up_tips(channels=[0], spots=[spot])\nexcept Exception:\n    spot.mark_errored()   # contents are now Unknown\n    raise\n\nspot.errored             # True\nisinstance(spot.get(), Unknown)   # True\n",[948,1733,1734,1746,1750,1765,1769,1775,1803,1811,1819,1823,1827,1835],{"__ignoreMap":962},[966,1735,1736,1738,1741,1743],{"class":968,"line":969},[966,1737,983],{"class":972},[966,1739,1740],{"class":976}," unitelabs.labware ",[966,1742,973],{"class":972},[966,1744,1745],{"class":976}," Unknown\n",[966,1747,1748],{"class":968,"line":980},[966,1749,998],{"emptyLinePlaceholder":997},[966,1751,1752,1755,1757,1760,1762],{"class":968,"line":994},[966,1753,1754],{"class":976},"spot ",[966,1756,1041],{"class":972},[966,1758,1759],{"class":976}," tip_rack[",[966,1761,1111],{"class":1050},[966,1763,1764],{"class":976},"]\n",[966,1766,1767],{"class":968,"line":1001},[966,1768,998],{"emptyLinePlaceholder":997},[966,1770,1771,1773],{"class":968,"line":1017},[966,1772,1472],{"class":972},[966,1774,1085],{"class":976},[966,1776,1777,1779,1782,1785,1787,1790,1793,1795,1798,1800],{"class":968,"line":1035},[966,1778,1625],{"class":972},[966,1780,1781],{"class":976}," hamilton.pipettes.pick_up_tips(",[966,1783,1784],{"class":1105},"channels",[966,1786,1041],{"class":972},[966,1788,1789],{"class":976},"[",[966,1791,1792],{"class":1146},"0",[966,1794,1527],{"class":976},[966,1796,1797],{"class":1105},"spots",[966,1799,1041],{"class":972},[966,1801,1802],{"class":976},"[spot])\n",[966,1804,1805,1807,1809],{"class":968,"line":1057},[966,1806,1538],{"class":972},[966,1808,1147],{"class":1146},[966,1810,1085],{"class":976},[966,1812,1813,1816],{"class":968,"line":1074},[966,1814,1815],{"class":976},"    spot.mark_errored()   ",[966,1817,1818],{"class":1175},"# contents are now Unknown\n",[966,1820,1821],{"class":968,"line":1079},[966,1822,1599],{"class":972},[966,1824,1825],{"class":968,"line":1088},[966,1826,998],{"emptyLinePlaceholder":997},[966,1828,1829,1832],{"class":968,"line":1097},[966,1830,1831],{"class":976},"spot.errored             ",[966,1833,1834],{"class":1175},"# True\n",[966,1836,1837,1840,1843],{"class":968,"line":1127},[966,1838,1839],{"class":1146},"isinstance",[966,1841,1842],{"class":976},"(spot.get(), Unknown)   ",[966,1844,1834],{"class":1175},[915,1846,1847,1850,1851,1854,1855,1857],{},[948,1848,1849],{},"mark_errored()"," works whether the spot was occupied or empty; the previous occupant is detached. Clearing the spot with ",[948,1852,1853],{},"spot.remove()"," discards the ",[948,1856,1723],{}," placeholder and restores the empty, non-errored state. Marking spots as errored keeps the deck model honest so downstream steps — and anyone reloading the saved deck — know not to rely on those positions.",[940,1859,1861],{"id":1860},"logging-for-traceability","Logging for traceability",[915,1863,1864],{},"Set up logging once at the top of your script, before any instrument connections:",[957,1866,1868],{"className":959,"code":1867,"language":961,"meta":962,"style":962},"import logging\n\nlogging.basicConfig(\n    level=logging.INFO,\n    format=\"%(asctime)s %(levelname)s %(name)s — %(message)s\",\n    handlers=[\n        logging.StreamHandler(),\n        logging.FileHandler(\"run.log\"),\n    ],\n)\n",[948,1869,1870,1876,1880,1885,1901,1929,1939,1944,1955,1960],{"__ignoreMap":962},[966,1871,1872,1874],{"class":968,"line":969},[966,1873,973],{"class":972},[966,1875,977],{"class":976},[966,1877,1878],{"class":968,"line":980},[966,1879,998],{"emptyLinePlaceholder":997},[966,1881,1882],{"class":968,"line":994},[966,1883,1884],{"class":976},"logging.basicConfig(\n",[966,1886,1887,1890,1892,1895,1898],{"class":968,"line":1001},[966,1888,1889],{"class":1105},"    level",[966,1891,1041],{"class":972},[966,1893,1894],{"class":976},"logging.",[966,1896,1897],{"class":1146},"INFO",[966,1899,1900],{"class":976},",\n",[966,1902,1903,1906,1908,1910,1913,1916,1919,1922,1925,1927],{"class":968,"line":1017},[966,1904,1905],{"class":1105},"    format",[966,1907,1041],{"class":972},[966,1909,1662],{"class":1050},[966,1911,1912],{"class":972},"%(asctime)s",[966,1914,1915],{"class":972}," %(levelname)s",[966,1917,1918],{"class":972}," %(name)s",[966,1920,1921],{"class":1050}," — ",[966,1923,1924],{"class":972},"%(message)s",[966,1926,1662],{"class":1050},[966,1928,1900],{"class":976},[966,1930,1931,1934,1936],{"class":968,"line":1035},[966,1932,1933],{"class":1105},"    handlers",[966,1935,1041],{"class":972},[966,1937,1938],{"class":976},"[\n",[966,1940,1941],{"class":968,"line":1057},[966,1942,1943],{"class":976},"        logging.StreamHandler(),\n",[966,1945,1946,1949,1952],{"class":968,"line":1074},[966,1947,1948],{"class":976},"        logging.FileHandler(",[966,1950,1951],{"class":1050},"\"run.log\"",[966,1953,1954],{"class":976},"),\n",[966,1956,1957],{"class":968,"line":1079},[966,1958,1959],{"class":976},"    ],\n",[966,1961,1962],{"class":968,"line":1088},[966,1963,1054],{"class":976},[915,1965,1966],{},"Log before and after every state-changing operation, not for debugging, but for audit and post-run analysis:",[957,1968,1970],{"className":959,"code":1969,"language":961,"meta":962,"style":962},"logging.info(\"Opening incubator door\")\nawait incubator.door.open()\nlogging.info(\"Incubator door open\")\n\nlogging.info(\"Moving plate: %s → %s\", source_well, dest_well)\nawait gripper.arm.move_plate(source=source_well, destination=dest_well)\nlogging.info(\"Plate move complete\")\n",[948,1971,1972,1982,1990,1999,2003,2022,2043],{"__ignoreMap":962},[966,1973,1974,1977,1980],{"class":968,"line":969},[966,1975,1976],{"class":976},"logging.info(",[966,1978,1979],{"class":1050},"\"Opening incubator door\"",[966,1981,1054],{"class":976},[966,1983,1984,1987],{"class":968,"line":980},[966,1985,1986],{"class":972},"await",[966,1988,1989],{"class":976}," incubator.door.open()\n",[966,1991,1992,1994,1997],{"class":968,"line":994},[966,1993,1976],{"class":976},[966,1995,1996],{"class":1050},"\"Incubator door open\"",[966,1998,1054],{"class":976},[966,2000,2001],{"class":968,"line":1001},[966,2002,998],{"emptyLinePlaceholder":997},[966,2004,2005,2007,2010,2012,2015,2017,2019],{"class":968,"line":1017},[966,2006,1976],{"class":976},[966,2008,2009],{"class":1050},"\"Moving plate: ",[966,2011,1659],{"class":972},[966,2013,2014],{"class":1050}," → ",[966,2016,1659],{"class":972},[966,2018,1662],{"class":1050},[966,2020,2021],{"class":976},", source_well, dest_well)\n",[966,2023,2024,2026,2029,2031,2033,2036,2038,2040],{"class":968,"line":1035},[966,2025,1986],{"class":972},[966,2027,2028],{"class":976}," gripper.arm.move_plate(",[966,2030,1106],{"class":1105},[966,2032,1041],{"class":972},[966,2034,2035],{"class":976},"source_well, ",[966,2037,1117],{"class":1105},[966,2039,1041],{"class":972},[966,2041,2042],{"class":976},"dest_well)\n",[966,2044,2045,2047,2050],{"class":968,"line":1057},[966,2046,1976],{"class":976},[966,2048,2049],{"class":1050},"\"Plate move complete\"",[966,2051,1054],{"class":976},[915,2053,2054,2055,2058],{},"The ",[948,2056,2057],{},"run.log"," file gives you a timestamped record of every physical action your script took. Many logs are automatically written and stored on the platform (API logs), others are available but not surfaced unless logging is explicitly set up (inbuilt SDK logs).",[940,2060,2062],{"id":2061},"safe-state-checklist","Safe-state checklist",[915,2064,2065],{},"Before finishing an error handler, check:",[2067,2068,2069,2076,2082,2088,2094,2100],"ol",{},[2070,2071,2072,2075],"li",{},[919,2073,2074],{},"Connections",": are open connections closed or returned to their pool?",[2070,2077,2078,2081],{},[919,2079,2080],{},"Held labware",": is the gripper parked? Is a pipette tip ejected?",[2070,2083,2084,2087],{},[919,2085,2086],{},"Instrument doors",": are incubator and centrifuge doors closed?",[2070,2089,2090,2093],{},[919,2091,2092],{},"Partial results",": have you written whatever data you collected so far?",[2070,2095,2096,2099],{},[919,2097,2098],{},"Notification",": if the method was running unattended, does someone know it failed?",[2070,2101,2102,2107,2108,2110],{},[919,2103,2104,2106],{},[948,2105,954],{}," safety",": does your ",[948,2109,954],{}," block avoid raising its own exception?",[940,2112,2114],{"id":2113},"next-steps","Next steps",[2116,2117,2118,2124,2129],"ul",{},[2070,2119,2120,2123],{},[935,2121,2122],{"href":597},"Operate",": define deck positions your error handlers can reference",[2070,2125,2126,2128],{},[935,2127,617],{"href":618},": tip ejection and liquid-handling-specific error patterns",[2070,2130,2131,2134],{},[935,2132,2133],{"href":420},"Automate → Error handling",": declare retry policy and checkpoint-based resumption instead of writing it yourself",[2136,2137,2138],"style",{},"html pre.shiki code .sxkbv, html code.shiki .sxkbv{--shiki-light:#A0111F;--shiki-default:#A0111F;--shiki-dark:#FF7B72}html pre.shiki code .sc-9e, html code.shiki .sc-9e{--shiki-light:#0E1116;--shiki-default:#0E1116;--shiki-dark:#E6EDF3}html pre.shiki code .s4qFZ, html code.shiki .s4qFZ{--shiki-light:#622CBC;--shiki-default:#622CBC;--shiki-dark:#D2A8FF}html pre.shiki code .sCx38, html code.shiki .sCx38{--shiki-light:#032563;--shiki-default:#032563;--shiki-dark:#A5D6FF}html pre.shiki code .sNqAu, html code.shiki .sNqAu{--shiki-light:#702C00;--shiki-default:#702C00;--shiki-dark:#FFA657}html pre.shiki code .sOiAX, html code.shiki .sOiAX{--shiki-light:#023B95;--shiki-default:#023B95;--shiki-dark:#79C0FF}html pre.shiki code .sIsDC, html code.shiki .sIsDC{--shiki-light:#66707B;--shiki-default:#66707B;--shiki-dark:#8B949E}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":962,"searchDepth":969,"depth":980,"links":2140},[2141,2142,2148,2149,2150,2151],{"id":942,"depth":980,"text":943},{"id":1230,"depth":980,"text":1231,"children":2143},[2144,2145,2146,2147],{"id":1235,"depth":994,"text":1236},{"id":1379,"depth":994,"text":1380},{"id":1448,"depth":994,"text":1449},{"id":1605,"depth":994,"text":1606},{"id":1704,"depth":980,"text":1705},{"id":1860,"depth":980,"text":1861},{"id":2061,"depth":980,"text":2062},{"id":2113,"depth":980,"text":2114},"Handle device failures, timeouts, and unexpected states safely in your lab automation scripts.","md",{},"\u002Fconcepts\u002Foperate\u002Ferror-handling",{"title":380,"description":2152},"QBOck7bwUs-teQm4NZy7qSpYfObMYgX9piRrEn_-5AU",[2159,2161],{"title":376,"description":2160,"path":377},"What the mock actually models — the validations it catches, the ones it doesn't, and why a script can pass the mock and still fail on hardware.",{"title":388,"description":2162,"path":389},"The top-level process in UniteLabs, defined by the scientific result it produces. It coordinates phases, data flow, and physical state, and runs the same way locally and on the platform.",1791294179238]