Visualizer Not Updating

I am working on simulating a protocol for Opentrons OT-2, and I have the visualizer running but it only shows the starting deck, and stays that way for the duration of the protocol. If I close the tab and open it again after the protocol is complete, it updates the deck to what it would look like after the completed method. Can anyone tell me what my issue might be and how I can get it to update in live time as the liquid is moving? Thank you!

import asyncio

from pylabrobot.liquid_handling import LiquidHandler, OpentronsOT2Backend

from pylabrobot.liquid_handling.standard import Mix

from pylabrobot.resources import OTDeck, Plate, Well, WellBottomType, create_ordered_items_2d

from pylabrobot.liquid_handling.backends import OpentronsOT2Simulator

from pylabrobot.resources.opentrons.load import load_ot_tip_rack

from pylabrobot.resources.coordinate import Coordinate

from pylabrobot.liquid_handling.backends import LiquidHandlerChatterboxBackend

from pylabrobot.visualizer.visualizer import Visualizer

from pylabrobot.resources import set_tip_tracking, set_volume_tracking

set_tip_tracking(True)

set_volume_tracking(True)

async def main():

deck = OTDeck()

lh = LiquidHandler(backend=OpentronsOT2Simulator(), deck=deck)

await lh.setup()



vis = Visualizer(resource=lh)

await vis.setup()

print("Visualizer is running. Open http://127.0.0.1:1337 in your browser.")




*#0 is left, 1 is right*

p20=1

p300=0

index_letters=\["A", "B", "C", "D", "E", "F", "G", "H"\]



*#Create Custom Labware*

plate_2 = Plate(

    name="costaralpaqua_96_wellplate_2200ul",

    size_x=127.76,

    size_y=85.47,

    size_z=72.82,

    ordered_items=create_ordered_items_2d(

        Well,

        num_items_x=12,

        num_items_y=8,

        dx=14.38,

        dy=11.25,

        dz=1,

        item_dx=9,

        item_dy=9,

        size_x=8.15,

        size_y=8.15,

        size_z=42.42,

        bottom_type=WellBottomType.V,

        max_volume=2200,

    ),

)

plate_1 = Plate(

    name="costar_96_wellplate_2200ul",

    size_x=127.76,

    size_y=85.47,

    size_z=43.82,

    ordered_items=create_ordered_items_2d(

        Well,

        num_items_x=12,

        num_items_y=8,

        dx=14.38,

        dy=11.25,

        dz=1,

        item_dx=9,

        item_dy=9,

        size_x=8.15,

        size_y=8.15,

        size_z=42.42,

        bottom_type=WellBottomType.V,

        max_volume=2200,

    ),

)

reservoir_1 = Plate(

    name="axygen_12_reservoir_22000ul",

    size_x=127.35,

    size_y=85.10,

    size_z=43.80,

    ordered_items=create_ordered_items_2d(

        Well,

        num_items_x=12,

        num_items_y=1,

        dx=14.98,

        dy=40.80,

        dz=1,

        item_dx=9,

        item_dy=0,

        size_x=8.00,

        size_y=71.00,

        size_z=37.50,

        bottom_type=WellBottomType.FLAT,

        max_volume=22000,

    ),

)

plate_3 = Plate(

    name="axygen_96_wellplate_1100ul 1",

    size_x=127.76,

    size_y=85.47,

    size_z=27,

    ordered_items=create_ordered_items_2d(

        Well,

        num_items_x=12,

        num_items_y=8,

        dx=14.24,

        dy=11.19,

        dz=1,

        item_dx=9,

        item_dy=9,

        size_x=8.71,

        size_y=8.71,

        size_z=23.48,

        bottom_type=WellBottomType.U,

        max_volume=1100,

    ),

)

plate_4 = Plate(

    name="axygen_96_wellplate_1100ul 2",

    size_x=127.76,

    size_y=85.47,

    size_z=27,

    ordered_items=create_ordered_items_2d(

        Well,

        num_items_x=12,

        num_items_y=8,

        dx=14.24,

        dy=11.19,

        dz=1,

        item_dx=9,

        item_dy=9,

        size_x=8.71,

        size_y=8.71,

        size_z=23.48,

        bottom_type=WellBottomType.U,

        max_volume=1100,

    ),

)

*#Load Labware*

tiprack_1 = load_ot_tip_rack(

    ot_name="opentrons_96_tiprack_300ul",

    plr_resource_name = "300uL Tip Rack 1"

)

tiprack_2 = load_ot_tip_rack(

    ot_name="opentrons_96_tiprack_300ul",

    plr_resource_name = "300uL Tip Rack 2"

)

tiprack_3 = load_ot_tip_rack(

    ot_name="opentrons_96_tiprack_300ul",

    plr_resource_name = "300uL Tip Rack 3"

)

tiprack_4 = load_ot_tip_rack(

    ot_name="opentrons_96_tiprack_300ul",

    plr_resource_name = "300uL Tip Rack 4"

)

tiprack_5 = load_ot_tip_rack(

    ot_name="opentrons_96_tiprack_300ul",

    plr_resource_name = "300uL Tip Rack 5"

)

tiprack_6 = load_ot_tip_rack(

    ot_name="opentrons_96_tiprack_300ul",

    plr_resource_name = "300uL Tip Rack 6"

)



*#Assign Deck Locations*

lh.deck.assign_child_at_slot(tiprack_1, slot=2)

lh.deck.assign_child_at_slot(tiprack_2, slot=3)

lh.deck.assign_child_at_slot(tiprack_3, slot=5)

lh.deck.assign_child_at_slot(tiprack_4, slot=6)

lh.deck.assign_child_at_slot(tiprack_5, slot=9)

lh.deck.assign_child_at_slot(tiprack_6, slot=8)

lh.deck.assign_child_at_slot(reservoir_1, slot=11)

lh.deck.assign_child_at_slot(plate_1, slot=1)

lh.deck.assign_child_at_slot(plate_2, slot=4)

lh.deck.assign_child_at_slot(plate_3, slot=10)

lh.deck.assign_child_at_slot(plate_4, slot=7)





*#Load Tips*

tiprack_1.fill()

tiprack_2.fill()

tiprack_3.fill()

tiprack_4.fill()

tiprack_5.fill()

plate_1.set_well_volumes(\[1000\]\*96)

plate_4.set_well_volumes(\[50\]\*96)

reservoir_1.set_well_volumes(\[20000, 20000, 20000, 20000, 9600, 20000, 0, 0, 0, 0, 0, 0\]) *#Wash Buffer*

wash_tips = \[tiprack_3, tiprack_4, tiprack_5\]




*#Start Method*



*#Equilibrate Beads*

for i in range(8):

    for m in range(12):

        index = index_letters\[i\] + str(m+1)

        await lh.pick_up_tips(tiprack_1\[index\], use_channels=\[p300\])

            

        await lh.aspirate(reservoir_1\["A6"\], vols=\[200\], use_channels=\[p300\])

        await lh.dispense(plate_4\[index\], vols=\[200\], use_channels=\[p300\])

        for j in range(10):

            await lh.aspirate(plate_4\[index\], vols=\[150\], use_channels=\[p300\])

            await lh.dispense(plate_4\[index\], vols=\[150\], use_channels=\[p300\])

        await lh.aspirate(plate_4\[index\], vols=\[250\], use_channels=\[p300\])

        await lh.dispense(plate_2\[index\], vols=\[250\], use_channels=\[p300\])

        await asyncio.sleep(1) *#Temporarily change this to 1*

        await lh.aspirate(plate_2\[index\], vols=\[200\], use_channels=\[p300\])

        await lh.dispense(reservoir_1\["A7"\], vols=\[200\], use_channels=\[p300\])

        await lh.return_tips()

        print("Checkpoint 1 " + str(i+1) + str(m+1))



for i in range(8):

    for m in range(12):        

        index = index_letters\[i\] + str(m+1)

        await lh.pick_up_tips(tiprack_2\[index\], use_channels=\[p300\])

        for k in range(4):

            await lh.aspirate(plate_1\[index\], vols=\[250\], use_channels=\[p300\])

            await lh.dispense(plate_2\[index\], vols=\[250\], use_channels=\[p300\], blow_out=True, blow_out_air_volume=\[50\])

        print("Checkpoint 2 " + str(i+1) + str(m+1))

        for l in range(9):

            await lh.aspirate(plate_2\[index\], vols=\[250\], use_channels=\[p300\])

            await lh.dispense(plate_2\[index\], vols=\[250\], use_channels=\[p300\])

        await lh.aspirate(plate_2\[index\], vols=\[250\], flow_rate=200, use_channels=\[p300\])

        await lh.dispense(plate_2\[index\], vols=\[250\], flow_rate=50, use_channels=\[p300\], blow_out=True, blow_out_air_volume=\[50\])

        *#Touch tip*

        

        *#Pause*

        await lh.move_channel_z(p300, 72) *#Fill this with top of well height*

        await asyncio.sleep(1) *#Temporarily change this to 1 from 10*



        for k in range(4):

            await lh.aspirate(plate_2\[index\], vols=\[250\], flow_rate=200, use_channels=\[p300\], offsets=\[Coordinate(x=0, y=0, z=4)\]) 

            await lh.dispense(plate_1\[index\], vols=\[250\], flow_rate=50, use_channels=\[p300\]) *#maybe add an offset to make it dispense at the top*

        print("Checkpoint 3 " + str(i+1) + str(m+1))

        await lh.return_tips()

        *#await lh.discard_tips()*



*#Wash Step*

for l in range(2):

    print("Checkpoint 4&5 " + str(l+1))

    for m in range(8):

        print("Checkpoint 6 " + str(m+1))

        for n in range(12):

            index = index_letters\[m\] + str(n+1)

            await lh.pick_up_tips(wash_tips\[l\]\[index\], use_channels=\[p300\])

            

            *#Determining which wash buffer reservoir to take from*

            if m < 2:

                wash_reservoir = 1

            if m >= 2 and m < 4:

                wash_reservoir = 2

            if m >= 4 and m < 6:

                wash_reservoir = 3

            if m >= 6 and m < 8:

                wash_reservoir = 4



            *#Transfer Wash Buffer to Plate*

            for o in range(2):

                await lh.aspirate(reservoir_1\["A"+str(wash_reservoir)\], vols=\[200\], use_channels=\[p300\]) *#has at z=2 but i changed labware*

                await lh.dispense(plate_2\[index\], vols=\[200\], mix=\[Mix(volume=200, repetitions=10, flow_rate=100)\], use_channels=\[p300\])

                

            *#Aspirate Wash Buffer*

            for o in range(2):

                await lh.aspirate(plate_2\[index\], vols=\[200\], use_channels=\[p300\], offsets=\[Coordinate(x=0,y=0,z=.5)\])

                await lh.dispense(reservoir_1\["A"+str(wash_reservoir+7)\], vols=\[200\], use_channels=\[p300\])

            await lh.return_tips()

            *#await lh.discard_tips()*



*#Elution Step*

for i in range(8):

    print("Checkpoint 7 " + str(i+1))

    for j in range(12):

        index = index_letters\[i\] + str(j+1)

        await lh.pick_up_tips(tiprack_6\[index\], use_channels=\[p300\])

        

        *#Transferring Elution Buffer to Wells + Resuspending*

        await lh.aspirate(reservoir_1\["A5"\], vols=\[100\], use_channels=\[p300\])

        await lh.dispense(plate_2\[index\], vols=\[100\], mix=\[Mix(volume=50, repetitions=5, flow_rate=100)\], use_channels=\[p300\]) *#Dispense at top -- 20 for blowout, might not work*



        *#Transferring Eluted Protein to Final Plate*

        await lh.aspirate(plate_2\[index\], vols=\[100\], use_channels=\[p300\])

        await lh.dispense(plate_3\[index\], vols=\[100\], use_channels=\[p300\], blow_out=True, blow_out_air_volume=\[50\]) 

        await lh.return_tips()

        *#await lh.discard_tips()*




await asyncio.Event().wait()

await vis.stop()

await lh.stop()

if _name_ == “_main_”:

asyncio.run(main())
1 Like

thanks for the bug report, looking into this