Agilent VWorks Driver Page#

This page has all the information specific to the Agilent VWorks driver and adapter.

Supported Agilent VWorks versions#

Agilent VWorks 13.1

Agilent VWorks Installer#

You can download the latest installer here.

Agilent VWorks Adapter config.yaml File#

config.yaml#
log:
  level: "DEBUG"
  loggerLevels:
    - logger: "tutorial"
      level: "DEBUG"

artificial:
  host: your-instance.artificial.com
  lab: lab_1a2b3c-4d5e-6f7g-8h9i-123456abcdef

adapter:
  name: VWorksTutorialAdapter
  remoteConfig: False
  allowAnySequenceId: True # Useful when running in a local dev container
  plugin: # all resources this adapter can connect to
    resource:
      name: "Bravo"  # user friendly name, unique in the adapter
      id: "asset_name" #This name should match with the devices key in the asset_sync section of this config
      driver:
        name: "vworks" # Driver name, this is a non-configurable string that needs to match the driver identity
        url: "http://vworks.webaddress.com:49835" #  URL of the hardware and driver
        resource_simulation: false     # Set to true to run simulation without hardware
        driver_simulation: false       # Set to true to run simulation without a driver
        cert_file: "adapter/certs/ca.crt"
        user_name: ""
        user_password: ""
  asset_sync:
    devices: # device string names/prefix must match resource id above
       "asset_name": { rid: "d1234567-34d0-4391-be64-7aef4e0b28be" }
  1. Fill in the correct URL and port for the VWorks device. (The IPv4 URL can be obtained on the device by running ipconfig in a command window. The port is listed in the running driver server window.)

  2. You may update the resource name above if you wish (any unique string will work).

  3. Fill in the user_name and password if needed.

  4. If you wish to run in simulation without hardware or without a driver, change resource_simulation or driver_simulation to true, respectively.

  5. Under asset_sync, match at least one of your devices to a Digital Twin asset ID. You can fill out the rest of the devices later. Consult the corresponding step in Hardware-Specific Adapter Setup.

  6. Update the artificial section to the correct host and lab. Consult the corresponding step in Hardware-Specific Adapter Setup for how to do this.

Agilent VWorks Adapter adapter/main/plugin.py File#

adapter/main/plugin.py file#
from artificial.adapter_common import ActionModulePlugin, action_modules
from artificial.adapter_common.plugin import PluginContext, plugin_config
from artificial.logging import get_logger
from artificial.resource_base.asset_syncer import ResourceAssetSyncer
from artificial.resource_base.models import SyncConfig
from artificial.vworks.actions import VWorksActions
from artificial.vworks.core import VWorksResource
from artificial.vworks.driver_client_simulator import VWorksDriverMock as Simulator
from artificial.vworks.event_handler import VWorksEventHandler
from artificial.vworks.models import PluginConfig

logger = get_logger(__name__)


@action_modules(VWorksActions)
class AdapterPlugin(ActionModulePlugin):
    """assemble resources components with resource configuration"""

    _cfg = plugin_config(PluginConfig)  # this will make PluginConfig show up in the adapter config UI

    async def setup(self, pctx: PluginContext) -> None:
        plugin_conf = self._cfg
        prog_config = pctx.config
        sync_config: SyncConfig = pctx.raw_config.to_dataclass(SyncConfig, 'adapter.asset_sync')
        logger.debug(f'sync_config loaded: {sync_config}')

        # all resources in the adapter use the same res_syncer
        syncer = pctx.asset_sync_manager_v1(f'ResourceSyncer-{prog_config.adapter.name}')
        res_syncer = ResourceAssetSyncer(syncer, sync_config)
        await res_syncer.initialize()

        # create instances of resources for this adapter
        resource = VWorksResource(
            pctx.alabPyBase,
            lab_id=prog_config.artificial.labId,
            adapter_id=prog_config.adapter.name,
            resource_id=plugin_conf.resource.id,
            name=plugin_conf.resource.name,
            res_syncer=res_syncer,
        )

        if resource:  # hook up action modules and event handlers
            resource.set_driver(driver_config=plugin_conf.resource.driver, simulator=Simulator())
            await resource.set_health_monitors(pctx.lab.health)
            self.add_module(VWorksActions(resource))
            logger.debug('base action module added.')

            # subscribe the events
            event_handler = VWorksEventHandler(resource)
            resource.add_event_handler(event_handler)

Agilent VWorks Adapter adapter/main/__main__.py File#

Copy the following list of actors into the file in place of the example actors.

actors = [
    ActorConfig(id='bravo', abilities={'run_protocol': 1}),
]

Agilent VWorks Adapter pyproject.toml Dependencies#

Add the needed dependencies to the [project] section of pyproject.toml by running the below in your terminal:

uv add artificial-vworks-adapter==1.1.*
uv add "artificial-protocol-runner-library>= 2.0.1, < 3.0.0"

Your pyproject.toml file should now include artificial-vworks-adapter and artificial-protocol-runner-library in the project dependencies section:

[project]
dependencies = [
  "artificial-vworks-adapter==1.1.*",
  "artificial-protocol-runner-library>= 2.0.1, < 3.0.0"
]

Agilent VWorks Simple Connectivity Workflow#

This workflow will run a method of your choosing and log a message in the UI upon successful completion. You will define which method to run in the request UI by inputting the method name with its full path (e.g., C://Methods//mymethod.med).

A couple of notes: #. After copying this code into a file, remember to replace the lab_guid in the workflow heading with the one from your Lab (most easily found by opening the Lab in Artificial and looking in the browser address bar). Consult Adding and Running a Simple Connectivity Test Workflow for more info.

  1. Update the variable section to reflect your protocol as you may have different variables or none.

from typing import List

from artificial.workflows.decorators import parameter, workflow
from artificial.workflows.runtime import show_info
from stubs.stubs_actions import VariableType, run_protocol_to_completion


@workflow('Simple Bravo Connectivity Test Workflow', 'simple_bravo_connectivity_test_workflow', 'lab_8ff750d9-b8c9-4a1b-b433-05437ce87ef2', interactive=True, quick=True)
@parameter('vworks_protocol_name', {'required': True, 'uiTitle': 'VWorks Protocol Name'})
async def simple_vworks_connectivity_test_workflow(vworks_protocol_name: str) -> None:
    params: List[VariableType] = [
        VariableType(var_name='run_now', var_value='true', var_type='TrueFalse'),
        VariableType(var_name='nplates', var_value='2', var_type='Numeric'),
        VariableType(var_name='run_count', var_value='3', var_type='Numeric'),
    ]
    await run_protocol_to_completion(vworks_protocol_name, params)
    await show_info('Congratulations, you successfully ran your hardware!', 'Hardware Success')