--- title: "Perspective Event Scripts" --- # Perspective Event Scripts > Perspective Event Scripts let you configure project level scripting that responds to key events in Perspective Sessions or on the Gateway. These scripts enable interaction between the client session, mobile devices, and the Gateway at various points in a session's lifecycle. Scripts fall into two categories: * **Gateway Event Scripts**: Events handled at the Gateway level, useful for centralized processing or offline functionality, like form submissions. * **Session Event Scripts**: Events tied to an individual Perspective Session. For example, session startup, shutdown, and keystroke. ## Gateway Event Scripts Gateway Event Scripts run in response to Perspective events that require centralized, Gateway-scoped execution. These events are often related to device independent workflows or features that support Offline Mode. Gateway Event Scripts are not tied to a specific active session context and may occur outside of a live connection (e.g., queued form submission from a disconnected mobile device). For a full list of available Gateway Event Scripts across the platform, see [Gateway Event Scripts](platform/scripting/scripting-in-ignition/gateway-event-scripts/gateway-event-scripts.md). ### Form Submission The Form Submission event script runs in the Gateway when a form is submitted from a Perspective Session. Unlike other events, this submission process is managed by an internal Form Submission Manager, which allows for offline submission, automatic retries, and response handling. ![](perspective-session-event-scripts/form-submission-script.png) #### Form Submission Parameters | Name | Description | | ---- | ----------- | | session | The Perspective Session handling the form submission event. | | name | The name of the submitted form. | | data | A dictionary containing the submitted form data, with key-value pairs matching the form fields. | | formContext | A dictionary containing additional context relevant to the submission, as defined by the user. | | sessionContext | A dictionary of session-related data captured at the time of submission, such as: Timestamp: The time when the event occurred.User information: Details about the user associated with the event.Device details: Information about the device used.Location data: The geographical location of the device (if available). | | retry | A boolean value indicating whether this is a resubmitted form due to a previous failure. | #### Form Submission Example This example logs form data in the Gateway and returns a validation error if a required field is missing. 1. In the Project Browser, navigate to **Perspective** > **Gateway Events**. ![](perspective-session-event-scripts/perspective-gateway-events.png) 2. Right-click **Form Submission** and select **New Form Submission Script**. ![](perspective-session-event-scripts/new-form-submission-script.png) 3. Enter **formSubmissionExample** into the Name field, and click **Create Form Submission**. ![](perspective-session-event-scripts/create-form-submission.png) 4. Add the following script to the editor and click **Save**. ```python # Example script for handling form submissions logger = system.util.getLogger("formSubmissionExample") # Log submission data logger.info("Received form submission: " + str(data)) # Example validation: Ensure 'email' field is provided if 'email' not in data or not data['email']: response = { "success": False, "title": "Missing Required Field", "message": "Email address is required.", "fieldErrors": {"email": {"title": "Required", "message": "Please enter your email."}} } else: response = {"success": True, "title": "Form Submitted", "message": "Thank you for your submission!"} # Return response response ``` #### Test the Example To test the form submission: 1. Add a Form component to a view. 2. Ensure the Form component name matches the Form Submission event name. 3. Configure the form with an Email input field and a Submit button. 4. Launch the Perspective Session and submit the form. 5. Verify the response: 1. If the email field is empty, an error will appear. 2. If the email is provided, a success message will be displayed. ## Session Event Scripts Session Event Scripts run in the Gateway scope and respond to events initiated by a Perspective Session. Session Events include: * [Startup](#startup) * [Shutdown](#shutdown) * [Page Startup](#page-startup) * [Authentication Challenge](#authentication-challenge) * [Message](#message) * [Keystroke](#keystroke) * [Barcode](#barcode) * [Bluetooth](#bluetooth) * [Accelerometer](#accelerometer) * [NFC](#nfc) ### Configuring Session Events To configure a Session Event Script: 1. In the **Project Browser**, navigate to **Perspective** > **Session Events**. ![](perspective-session-event-scripts/perspective-session-events.png) 2. Select the event type you want to configure. :::note If configuring **Keystroke** or **Message** scripts, right-click the event folder and select **New Script**. ::: 3. Add your script in the provided editor. 4. Click **Save**. ### Startup The Startup event script runs when a Session starts. The Gateway has access to the session object and all its properties. ![](perspective-session-event-scripts/startup-session-event.png) You can use custom Session properties to pass information between the Session and the Gateway. #### Startup Parameters | Name | Description | | --- | ----------- | | session | Represents the Perspective Session that is starting. The session object contains all Session properties. | #### Startup Example This example logs the Session start time in a database. **Create a Named Query** 1. In **Named Queries**, create a new query called **Startup Query**. 2. Set the **Query Type** to **Update Query**. 3. Add a **Value type parameter** named `SessionID` (string). 4. Enter the following query: ```sql title="Startup Query" INSERT INTO sessions (session_id, start_time) VALUES (:SessionID, CURRENT_TIMESTAMP) ``` **Add the Startup Script** 1. In the **Project Browser**, navigate to **Perspective** > **Session Events** > **Startup**. 2. Enter the following script: ```python title="Startup Script" # Log the Session start time. queryParams = {'sessionID': session.props.id} system.db.runNamedQuery('My Project', 'Startup Query', queryParams) ``` 3. Click **Save**. **Test the Example** 1. Open a Perspective Session on a mobile device or browser. 2. Verify the database has a new entry in the **sessions** table with the Session ID and start time. ### Shutdown The Shutdown event script runs when a Session ends. The Gateway has access to the session object and all its properties. You can use custom Session properties to pass information between the Session and the Gateway. A Shutdown script executes when a Session ends due to: * The Session closes due to a timeout. Session timeout is configurable in the **Perspective** > **General** section of [Project Properties](/ignition-modules/perspective/perspective-project-properties.md). * The user losing authorization. * Gateway redundancy failing over. * Licensing issues preventing access. * The project being deleted or made unrunnable. :::note Closing a browser tab **does not immediately close a Session**. The Session will remain open until it **times out**. ::: ![](perspective-session-event-scripts/shutdown-session-event.png) #### Shutdown Parameters | Name | Description | | ---- | ----------- | | session | Represents the **Perspective Session** that is ending. The session object contains all Session properties. | #### Shutdown Example This example logs the Session end time in a database. **Create a Named Query** 1. In **Named Queries**, create a new query called **Shutdown Query**. 2. Set the **Query Type** to **Update Query**. 3. Add a **Value type parameter** named SessionID (string). 4. Enter the following query: ```sql title="Shutdown Query" UPDATE sessions SET end_time = CURRENT_TIMESTAMP WHERE session_id = :SessionID ``` **Add the Shutdown Script** 1. In the **Project Browser**, navigate to **Perspective** > **Session Events** > **Shutdown**. 2. Enter the following script: ```python title="Shutdown Script" # Log the Session end time. queryParams = {'sessionID': session.props.id} system.db.runNamedQuery('My Project', 'Shutdown Query', queryParams) ``` 3. Click **Save**. **Test the Example** 1. Open a Perspective Session on a mobile device or browser. 2. Close the Session using one of the methods described above and wait for the timeout period to pass.. 3. Verify the database entry for the Session ID has an updated end time. ### Page Startup This script runs in the Gateway when a Perspective page starts in a new tab or window. :::note Navigating to an already open page does not trigger the Page Startup event (such as when using [`system.perspective.navigate`](appendix\scripting-functions\system-perspective\system-perspective-navigate.md)). ::: ![](perspective-session-event-scripts/page-startup-session-event.png) #### Page Startup Parameters | Name | Description | | ---- | ----------- | | page | Represents the newly created page. Use `.props.` to access page properties. | #### Page Startup Example ```python title="Accessing Page Properties" pageid = page.props.pageId # Retrieves the page ID. pagePath = page.props.path # Retrieves the page path. sessionId = page.session.props.id # Retrieves the session ID. ``` ### Authentication Challenge This script runs in the Gateway when a user completes an authentication challenge. ![](perspective-session-event-scripts/auth-challenge-session-event.png) #### Authentication Challenge Parameters | Name | Description | | ---- | ----------- | | session | An object that references the Project Session that triggered the authentication challenge. Use this to identify the specific Session that triggered the authentication challenge. | | payload | The opaque payload provided by the initial Authentication Challenge Action or Scripting function invocation. | | result | A result object that can be parsed by the result functions below. | **Results Functions** | Function | Description | | -------------- | ----------------------- | | isSuccess() | Returns true if the authentication challenge was a success. If true, optionally call **getAsSuccess()** to get the result as a **Result.Success** object for further parsing. If false, optionally call **getAsError()** to get the result as a **Result.Error** object for specific details pertaining to the error. | | getAsSuccess() | Returns the result as a **Result.Success** object if the result is successful, otherwise throws an **UnsupportedOperationException** if the result is an error. Check **isSuccess()** or **isError()** before calling this function to ensure you get the correct result type.**Note**: It is not necessary to call **getAsSuccess()**. If **isSuccess()** returns true, the result type is **Result.Success**, so all of the properties and functions of a **Result.Success** object are available on the original result reference. | | isError() | Returns true if the authentication challenge resulted in an error. If true, optionally call **getAsError()** to get the result as a **Result.Error** object for specific details pertaining to the error. | | getAsError() | Returns the result as a **Result.Error** object if the result is an error, otherwise throws an **UnsupportedOperationException** if the result is successful. Check **isSuccess()** or **isError()** before calling this function to ensure you get the correct result type.**Note**: It is not necessary to call **getAsError()**. If **isError()** returns true, the result type is **Result.Error**, so all of the properties and functions of a **Result.Error** object are available on the original result reference.| **Result Objects** This object contains different properties depending on whether the authentication challenge result is a success or an error. **Result.Success** An object that represents a successful authentication challenge result. Call getContext() to return a WebAuthUserContext object with the following properties. | Property | Description | | --- | --- | | idp | The Identity Provider that challenged the user. | | securityZones | A string array containing the names of the security zones associated with the challenged user. | | user | A **WebAuthUser** object that contains the properties in the User Properties table below. | | securityLevels | An array of **SecurityLevelConfig** objects representing all of the security levels associated with the challenged user. | **User Properties** | Property | Description | | --------- | --------------------------------------------------------------------------------- | | id | The unique identifier associated with the challenged user | | userName | The challenged user’s username. | | firstName | The challenged user’s first name, or null / None if not defined for this user. | | lastName | The challenged user’s last name, or null / None if not defined for this user. | | email | The challenged user’s email address, or null / None if not defined for this user. | | roles | The challenged user’s roles as a string array. | **Result.Error** An object that represents an error authentication result. It can be parsed by the following functions. | Function | Description | | ---------------- | ----------------- | | isGeneric() | Returns true if the error is not related to a timeout or user cancellation. Optionally call **getAsGeneric()** to get the **Result.Error** as a **Result.Error.Generic** object for specific details pertaining to the generic error. | | getAsGeneric() | Returns the result as a **Result.Error.Generic** object if the error is generic, otherwise throws an **UnsupportedOperationException**. Check isGeneric() before calling this function to ensure you get the correct result type.**Note**: It is not necessary to call **getAsGeneric()**. If **isGeneric()** returns true, the result type is **Result.Error.Generic**, so all of the properties and functions of a **Result.Error.Generic** object are available on the original result reference. | | isTimeout() | Returns true if the error is due to a timeout. Optionally call **getAsTimeout()** to get the **Result.Error** as a **Result.Error.Timeout** object for specific details pertaining to the timeout error. | | getAsTimeout() | Returns the result as a **Result.Error.Timeout** object if the error is due to a timeout, otherwise throws an **UnsupportedOperationException**. Check **isTimeout()** before calling this function to ensure you get the correct result type.**Note**: It is not necessary to call **getAsTimeout()**. If **isTimeout()** returns true, the result type is **Result.Error.Timeout**, so all of the properties and functions of a **Result.Error.Timeout** object are available on the original result reference. | | isCancelled() | Returns true if the error is due to user cancellation. Optionally call **getAsCancelled()** to get the **Result.Error** as a **Result.Error.Cancelled** object for specific details pertaining to the cancellation error. | | getAsCancelled() | Returns the result as a **Result.Error.Cancelled** object if the error is due to user cancellation, otherwise throws an **UnsupportedOperationException**. Check **isCancelled()** before calling this function to ensure you get the correct result type.**Note**: It is not necessary to call **getAsCancelled()**. If **isCancelled()** returns true, the result type is **Result.Error.Cancelled**, so all of the properties and functions of a **Result.Error.Cancelled** object are available on the original result reference. | **Result.Error Objects** This object contains different properties depending on the cause of the authentication error. | Object | Description | | ---------------------- | --------------- | | Result.Error.Generic | An object representing a generic error authentication result. Call **getMessage()** to return a diagnostic message pertaining to the error, or null if such a message does not exist. | | Result.Error.Timeout | An object representing a timeout error authentication result. Call **getTimeout()** to return the integer timeout value (in minutes) that that was used to configure the timeout. | | Result.Error.Cancelled | An object representing an error result due to user cancellation. This object has no functions or properties. | #### Authentication Challenge Example This script determines whether a user can proceed with an action after a completed [Authentication Challenge Action](ignition-modules\perspective\working-with-perspective-components\component-events-and-actions.md#authentication-challenge-action). The action is allowed only if the authenticated user has the **supervisor** role. If authorization fails or an error occurs, the script logs the result. ```python title="Handling an Authentication Challenge Result" if result.isSuccess(): # Parse the authentication result context = result.getAsSuccess().getContext() user = context.user roles = user.roles # Check if the user has the "supervisor" role if "supervisor" in roles: proceedWithSomeAction() # Execute the action else: # Log unauthorized access logger = system.util.getLogger("Authentication Challenge") logger.info("%s is not authorized" % user.userName) # Handle authentication failure else: error = result.getAsError() logger = system.util.getLogger("Authentication Challenge") # Log the error based on its type if error.isGeneric(): logger.info(error.getAsGeneric().getMessage()) elif error.isTimeout(): timeout = error.getAsTimeout().getTimeout() logger.info("Authentication challenge timed out after %d minutes." % timeout) elif error.isCancelled(): logger.info("Authentication challenge was cancelled.") else: logger.info("Unknown authentication error occurred.") ``` ### Message The Message event script runs when a Session receives a message from [system.util.sendMessage](appendix\scripting-functions\system-util\system-util-sendMessage.md) or [system.util.sendRequest](appendix\scripting-functions\system-util\system-util-sendRequest.md). :::note Session Message Handlers are different from [component-based message handlers](component-message-handlers.md), which are accessed with [system.perspective.sendMessage](appendix\scripting-functions\system-perspective/system-perspective-sendMessage.md). Session Message Handlers cannot be called using system.perspective.sendMessage. ::: ![](perspective-session-event-scripts/message-session-event.png) :::tip For user-driven operations, you can use [system.perspective.getSessionInfo](appendix/scripting-functions/system-perspective/system-perspective-getSessionInfo.md) to retrieve session data and filter sessions by specific users. ::: #### Message Parameters | Name | Description | | ---- | ----------- | | session | The Perspective Session that is handling this message. | | payload | Retrieve them with a subscript, e.g., `myObject = payload['argumentName']` | #### Message Example This example demonstrates how to configure a Session Message Handler to log messages received from system.util.sendMessage. **Configure a Message Handler** 1. In the **Project Browser**, navigate to **Perspective** > **Session Events**. 2. Right-click the **Message** folder and select **New Message Script**. 3. Enter "messageScript" as the script name. 4. Click **Create Message**. 5. Add the following script: ```python title="Logging Incoming Messages" message = payload["message"] sessionId = session.props.id logger = system.util.getLogger("SessionMessage") logger.info("Session %s received message: %s" % (sessionId, message)) ``` ![](perspective-session-event-scripts/message-example.png) 6. Click **Save**. **Send a Message Using a Button** 1. Add a **Button** component to a view. 2. Right-click the Button component and select **Configure Events**. 3. On the Event Configuration screen, select **Component Events** > **onActionPerformed**. 4. Click the **Add** icon and select **Script**. 5. Enter the following script: ```python title="Sending a Message to the Session" system.util.sendMessage("samplequickstart", "messageScript", {"message": "Hello World"}, "S") ``` ![](perspective-session-event-scripts/onActionPerformed-script.png) 6. Click **OK**. 7. Click **Save**. **Test the Example** 1. Launch a Perspective Session. 2. Click the Button to send a message. 3. Navigate to **Gateway** > **Diagnostics** > **Logs** to verify that the message was received. ### Keystroke Keystroke scripts run when a Perspective Session detects a KeyboardEvent that matches either a single key or a regex pattern. * **Single Key**: Matches on key press (keyDown) or key release (keyUp). * **Regex Match**: Always detected on key release. :::info Keystroke event scripts can be triggered by keyboards or any HID barcode scanner that generates KeyboardEvent data. ::: ![](perspective-session-event-scripts/keystroke-session-event.png) Keystroke detection is only active inside a Perspective Session and does not function in the Designer. :::note The device triggering the keystroke event must generate a KeyboardEvent. HID barcode scanners generate KeyboardEvents because they simulate physical keyboard input. Scanners and input devices that do not create KeyboardEvents will not trigger this logic. ::: #### Keystroke Parameters | Name | Description | | ---- | ----------- | | page | Represents the current page. See the Page Arguments table below for parameter arguments. | | event | Contains details about the Keyboard Event. See the Event Arguments table below for parameter arguments. | **Page Arguments** Arguments for the Keystroke Page parameter. | Argument | Description | | -------- | ----------- | | props | Properties of the page object. | | session | Represents the current session. | **Event Arguments** Arguments for the Keystroke Event parameter. | Argument | Description | | ----------- | ----------- | | altKey | True if the Alt (Option on macOS) key was active when the event was generated. | | code | A string representing the physical key code. | | ctrlKey | True if the Control (Ctrl) key was active when the event was generated. | | isComposing | True if the event occurred between [compositionstart](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event) and [compositionend](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionend_event). | | key | A string representing the key value of the event. | | location | A number indicating the location of the key on the keyboard or input device. | | metaKey | True if the Meta key (⌘ Command, ⊞ Windows) was active when the event was generated. | | repeat | True if the key was held down long enough to repeat automatically. | | shiftKey | True if the Shift key was active when the event was generated. | | matches | A list where the first entry is the matched text for the regex, and all subsequent entries are capture group contents. | #### Single Key Match For single key matches, the match can be either: * A physical key typed * The code generated by the key Modifiers (Alt, Ctrl, Shift, Meta/Command) can be detected in the event data. ![]() Additionally, key event matches include advanced settings: * **Capture Phase**: Executes the script before other interface events. By default, key events run during the bubbling phase, meaning they execute after other events in the Document Object Model (DOM). * **Prevent Default**: Stops default browser actions (e.g., form submission, page navigation) for a given key press. * **Stop Propagation**: Prevents the key event from affecting deeper DOM elements (e.g., text inputs). #### Regex Match For a regular expression (regex) match, the match is based on: * A regex pattern * A match buffer (stores the most recently typed characters) The buffer length should be set to the exact number of characters needed to match the regex. #### Keystroke Example (Regex Match) This example updates a custom Session property when a regex match is found. 1. Add a **Label** component to a view. 2. Create a **custom Session property** called `scannerInput`. 3. Bind the **Label’s text** to the **custom Session property**. 4. In the Project Browser**, navigate to **Perspective** > **Session Events**. 5. Right-click **Keystroke** and select **New Key Event Script**. 6. Enter a name and click **Create Keystroke**. 7. Under **Event Mode**, select **Regex Match**. ![](perspective-session-event-scripts/keystroke-regex.png) 8. Enter the **regex pattern** to detect: * Example: `[0-9]{12}@$` (matches **12 digits followed by @**). 9. Set **Match Buffer Length** to `13` (minimum required characters). 10. Add the following script: ```python title="Updating a Session Property on a Regex Match" page.session.custom.scannerInput = "Match found" ``` 11. Click **Save**. **Test the Example** 1. Launch a Perspective Session. 2. Open the view with the Label. 3. Type characters matching the regex pattern. 4. The Label’s text updates when a match is found. ![](perspective-session-event-scripts/40-9rnUTCPfp4.gif) ### Perspective App Event Scripts When the Perspective App is running on a mobile device, it enables users to use tools available on the device, such as GPS location data, the camera, or the accelerometer. The remaining Session events are designed specifically to handle the Perspective App Actions. #### Barcode The scanned barcode action can make use of a mobile device's built in camera. **Barcode Parameters** | Name | Description | | ---- | ----------- | | session | An object that references the project Session that called the Barcode Scanned event. Use this to identify the specific Session that scanned the barcode. | | data | The data returned from the barcode scan. Access the underlying barcode data using:# The value that was scanneddata.text# An integer representing a unix timestamp of when the barcode was scanneddata.timestamp Version 0.98 of the Perspective Mobile App added the following property:# The type of barcode that was scanned.data.barcodeType | | context | The user defined context object that can be defined on the action. | **Barcode Example** This example will scan a barcode, and write its value to a tag. 1. For this example, drag a Button component and a Label component onto a view. 2. Create a new Memory tag with a data type of String. Set the value to **Please scan a barcode**. ![]() 3. Bind the text of the Label to the new tag. ![](perspective-session-event-scripts/12-2019-04-04_16-57-50-a.png) 4. Right-click on the Button component and choose **Configure Events**. 5. On the Event Configuration screen, select **Mouse Events** > **onClick**. 6. Click the **Add** icon and select **Scan Barcode** action. ![](perspective-session-event-scripts/14-2021-02-16_15-47-25.png) 7. Click **OK**. Next we need to set up a session event so that Perspective knows how to interpret the scanned barcode data. 8. Under the Project Browser navigate to **Perspective** > **Session Events**, and select **Barcode**. ![](perspective-session-event-scripts/barcode-session-event.png) 9. Add the following script to the page: ```python system.tag.writeAsync(['[default]New Tag 5'], [data.text]) ``` :::note We used the tag created for this example, New Tag 5. You can enter your own tag name if different. ::: ![](perspective-session-event-scripts/barcode-example.png) 10. Save your project. **Test the Example** To test the example, open the Perspective App on your mobile device and load the project. 1. Click Scan Barcode. ![](perspective-session-event-scripts/18-2019-04-05_14-54-03.png) 2. If this is the first time scanning a barcode, you'll get a message requesting permission for Perspective to take pictures and record. ![](perspective-session-event-scripts/19-2019-04-04_13-01-44.png) 3. Click Allow. 4. You can now use the camera on the mobile device to scan the barcode. ![](perspective-session-event-scripts/20-2019-04-04_13-02-15.png) 5. Ignition scans the barcode. Once it recognizes the barcode, the script will run and the text is written to the tag. The Label then shows the new tag value. ![](perspective-session-event-scripts/21-2019-04-04_13-02-42.png) #### Bluetooth This Session Event Script sends received Bluetooth advertising data to Perspective. It supports iBeacon and Eddystone formats. * Eddystone will work on iOS and Android * iBeacon on iOS requires user to specify the specific region (iBeacon UUID) located on Session props bluetooth.config.iBeaconRegion. :::note Bluetooth "advertising data" is the name of the communication data according to the Bluetooth spec. There is no connection to advertising as an industry. ::: ![](perspective-session-event-scripts/bluetooth-session-event.png) **Bluetooth Parameters** | Name | Description | | ---- | ----------- | | session | An object that references the Project Session. | | data | List of buffered advertising data. The data comes in as a data object, which has various parts. See the example output below. | **Example Output** ```json=Example output { "values": [ { "rssi":-48, "timestamp":1570147485167, "manufacturerData":{ "companyId":6, "dataBase64Encoded":"AQkgAl_edccdnHClMvecMCiM--aAkLHAPibd" } }, { "rssi":-48, "timestamp":1570147486012, "serviceUUIDs":[ "FEAA" ], "serviceData":{ "uuid":"FEAA", "dataBase64Encoded":"AOyqqqqqqqqqqqqqAAAAAAAA" }, "eddystoneUID":{ "txPower":-20, "namespaceID":"AAAAAAAAAAAAAAAAAAAA", "instanceID":"000000000000" } }, { "rssi":-54, "timestamp":1570147485919, "manufacturerData":{ "companyId":76, "dataBase64Encoded":"AhV88isfQjVLY4VnXXfYqpTyAAAAAL8=" }, "iBeacon":{ "uuid":"7CF22B1F-4235-4B63-8567-5D77D8AA94F2", "major":0, "minor":0, "txPower":-65 } }, { "rssi":-54, "timestamp":1570147485987, "manufacturerData":{ "companyId":65535, "dataBase64Encoded":"vqwSNFZ4EjQSNBI0EjRWeJASAAAAAOwA" }, "AltBeacon":{ "manufacturerId":65535, "uuid":"12345678-1234-1234-1234-123456789012", "instance":"00000000", "txPower":-20, "manufacturerReserved":"00" } } ] } ``` #### Accelerometer The Accelerometer event is only used when data is coming in from a batched [Accelerometer Action](ignition-modules\perspective\working-with-perspective-components\component-events-and-actions.md#accelerometer-action). **Accelerometer Properties** | Name | Description | | ---- | ----------- | | session | An object that references the Project Session that called the Accelerometer Data Received event. Use this to identify the specific Session that triggered the batching of accelerometer data. | | data | The data returned from the batched accelerometer. The data comes in as a data object, which has various parts. Access the various parts like: logger = system.util.logger('accelerometer')for row in data.values.data: logger.info('X:' + str(row['x'])) logger.info('Y:' + str(row['y'])) logger.info('Z:' + str(row['z'])) | | context | The user defined context object that can be defined on the action. | **Accelerometer Example** This example will write accelerometer data to the Gateway logs. 1. Place a Button component onto a view. 2. Next right-click on the Button component and choose **Configure Events**. 3. On the Event Configuration screen, select **Mouse Events** > **onClick**. 4. Click the **Add** icon and select **Accelerometer** action. 1. Select **Batch** mode. 2. Set a **Sample Rate** of 400. 3. Set a **Duration** of 2000. ![](perspective-session-event-scripts/23-2020-05-08_14-49-02.png) 5. Click **OK**. Next we need to set up a Session Event so that Perspective knows how to interpret the accelerometer data. 6. Select **Accelerometer** under the **Perspective** > **Session Events** list. ![](perspective-session-event-scripts/accelerometer-session-event.png) 7. Add the following script to the page: ```python # This script will take the accelerometer data and print it to the Gateway logs. # Create the logger. logger = system.util.logger('accelerometer') # Loop through the list of batched events and pull out the x, y, and z values to print to the Gateway logs. for row in data.values.data: logger.info('X:' + str(row['x']) + ', Y:' + str(row['y']) + ', Z:' + str(row['z'])) ``` 8. Save your project. **Test the Example** To test the example, open the Perspective App on your mobile device and load the project. 1. Click the Accelerometer button. 2. The script will record accelerometer data for the next two seconds, so move the phone around. 3. After the two seconds, you should see the logged information appear in the Gateway logs. #### NFC The NFC event is used when the [NFC Action](../working-with-perspective-components/component-events-and-actions.md#scan-ndef-nfc-action) is used and the mobile device scans an NFC tag. **NFC Properties** | Name | Description | | ---- | ----------- | | session | An object that references the Project Session that called the NFC Ndef Scanned event. Use this to identify the specific Session that scanned the NFC tag. | | data | The data returned from the NFC tag scan. The data object is a list which can contain multiple records from a single NFC tag. Access the underlying NFC data using:logger = system.util.logger('NFC')for row in data: logger.info('Type:' + str(row['type'])) logger.info('Type Name Format:' + str(row['typeNameFormat'])) logger.info('Payload:' + str(row['payload'])) logger.info('String:' + str(row['string'])) logger.info('Bytes:' + str(row['bytes'])) | | context | The user defined context object associated with the NFC scan event. | **NFC Compatibility** NFC tag types must be NDEF-formatted as one of the following types: * NFC_FORUM_TYPE_1 based on ISO14443A * NFC_FORUM_TYPE_2 based on ISO14443A * NFC_FORUM_TYPE_3 based on JIS X 6319-4 * NFC_FORUM_TYPE_4 based on ISO14443A/B **NFC Example** This example will write the NFC tag data to the Gateway logs. 1. Place a Button component onto a view. 2. Right-click on the Button component and choose **Configure Events**. 3. On the Event Configuration screen, select **Mouse Events** > **onClick**. 4. Click the **Add** icon and select **Scan Ndef NFC** action. 5. Select **Single** mode, then click **OK**.![](perspective-session-event-scripts/27-2020-05-08_15-00-28.png) 6. Next we need to set up a Session Event so that Perspective knows how to interpret the NFC data. Select **NFC** under the **Perspective** > **Session Events** list. ![](perspective-session-event-scripts/nfc-session-event.png) 7. Add the following script to the page: ```python # This script will take the NFC data and print it to the Gateway logs. # Create the logger. logger = system.util.logger('NFC') # Loop through the list of records stored in the NFC tag and pull out the type, type name format, payload, string data, and raw byte data from each record and print it to the Gateway logs. for row in data: logger.info('Type:' + str(row['type']) + ', Type Name Format:' + str(row['typeNameFormat']) + ', Payload:' + str(row['payload']) + ', String:' + str(row['string']) + ', Bytes:' + str(row['bytes'])) ``` 8. Save your project. **Test the Example** To test the example, open the Perspective App on your mobile device and load the project. 1. Click the NFC button. * After clicking the button, the script will pass the next NFC tag scanned to the script to be handled. 2. After scanning an NFC tag, you should see the logged information appear in the Gateway logs.