# Subscribing to Precision I/O Events - OnStartup

Note: This example assumes that your application has a connected Communications Card device named CommCard. Also, keep in mind that your script must include a reference to Cognex.VisionPro.Comm and a similar Using statement.

The following OnStartup script configures the event and adds it to the HostNotification collection:

    // Get the connected comm card
    //
    if(! $Devices.CommCard.IsConnected)
    	{
    	$System.Log.Write("Connected CommCard Device not found.");
    	return null;
    	}

    // Access the underlying VisionPro object

    CogCommCard card = $System.GetInternalObject("Devices.CommCard") as CogCommCard;

    // access the discrete io object

    CogDiscreteIOAccess dioAccess = card.DiscreteIOAccess;
    CogPrio mPrio = dioAccess.GetActivePrecisionIO();

    // create the precision I/O event.

    if (mPrio != null)
    	{
    	mPrio.Events.Clear();
    	mPrio.DisableEvents( );

    	CogPrioEvent turnOnLight = new CogPrioEvent( );
    	turnOnLight.Name = "EventCapture";

    	CogPrioEventCauseLine mCause = new CogPrioEventCauseLine
    	(CogPrioBankConstants.InputBank0, 0, CogPrioLineTransitionConstants.LowToHigh);
    	turnOnLight.CausesLine.Add(mCause);

    	// Turn on the light for 1 second after a 3 second delay
    	CogPrioEventResponseLine mResponse = new CogPrioEventResponseLine
    	(CogPrioBankConstants.OutputBank0, 0, CogPrioOutputLineValueConstants.SetHigh, 1000, CogPrioDelayTypeConstants.Time, 3000);
    	turnOnLight.ResponsesLine.Add(mResponse);

           // Now create an event handler and assign it to a tag.
           // The event handler will call the user script
           // $HandlePrIOEvent

           $PRIOEventHandler = (CogPrioEventHandler)((sender, e) =>
           {

           // Note that you should never allow event handlers to
           // throw unhandled exceptions as this will cause
           // Designer to crash.

    	try
      	{
    		$HandlePrIOEvent(sender, e);
    	}
    	catch(Exception exception)
    	{
    		$System.Log.Write(exception.Message);
    	}});

    	turnOnLight.HostNotification += (CogPrioEventHandler) $PRIOEventHandler;

    	// Adds this event to the event collection

    	mPrio.Events.Add(turnOnLight);

    	if (!mPrio.Valid)
    		{
    		$System.Log.Write("Invalid PrIO state: " + mPrio.ValidationErrorMsg);
    		}
    	else
    		{
    		mPrio.EnableEvents();
    		}
    	}

Your event handling script ($HandlePrIOEvent in the example above), is called with two arguments, the object that invoked the event and a CogPrioEventArgs that provides information about the state of the Precision I/O substation at the time that the event fires.

There are some important restrictions to keep in mind while writing event notification functions:

- You should avoid writing an event handler that takes a long time to execute.
- Your event handler must not throw any unhandled exceptions
- Your event handler should not attempt to manipulate any HMI elements
- You should unregister your delegate function on application shutdown.

The following script shows how you can access the information in the CogPrioEventArgs object to update system tags:

Note: Your script must include a reference to Cognex.VisionPro.Comm and a similar Using statement.

    // Cast the argument to the correct type
    //
    CogPrioEventArgs eArgs = (CogPrioEventArgs) e;

    // Set tag values for the line state and timestamp
    //
    $LineState = eArgs.State.Line(CogPrioBankConstants.InputBank0 ,0);
    $TimeStamp = eArgs.State.TimeStamp.ToString();

The following OnShutdown script shows how you remove the notification handler delegate function:

    // Get the connected comm card
    if(!$Devices.CommCard.IsConnected)
    {
      $System.Log.Write("Connected Comm Card Device not found.");
      return null;
    }

    // Access the underlying VisionPro object

    CogCommCard card =  $System.GetInternalObject("Devices.CommCard") as CogCommCard;

    if(card == null)
    {
      $System.Log.Write("Comm Card Internal Object not found.");
      return null;
    }

    // Get a reference to the Prio object.
    CogPrio prio =  card.DiscreteIOAccess.GetActivePrecisionIO();

    if (prio == null)
    {
      $System.Log.Write("Precision I/O Internal Object not found.");
      return null;
    }

    // Disable events during configuration

    prio.DisableEvents( );

    // remove the host notification event handler, retrieving it from the global tag.

    prio.Events["EventCapture"].HostNotification -=  (CogPrioEventHandler) ($PRIOEventHandler);

    // Always check the valid state of the prio object.
    // If Valid is false the events will not be configured on the Comm Card.

    if (!prio.Valid)
    {
      $System.Log.Write("Invalid PrIO state: " + prio.ValidationErrorMsg[0]);
    }
    else
    {
      // Done configuring events. Call Enable.
      prio.EnableEvents();
    }