# Musson Industrial's Embr-Periscope Module

**URL:** <https://forum.inductiveautomation.com/t/musson-industrials-embr-periscope-module/99047>\
**Category:** 3rd Party Modules\
**Tags:** perspective\
**Created:** [November 24, 2024, 10:26pm UTC](https://forum.inductiveautomation.com/t/musson-industrials-embr-periscope-module/99047 "2024-11-24T22:26:31Z")\
**Posts on this page:** 1\
**Showing post:** 82

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [March 3, 2026, 8:15am UTC](https://forum.inductiveautomation.com/t/musson-industrials-embr-periscope-module/99047/82 "2026-03-03T08:15:12Z")

</div>

# Release Notice

[Embr v8.1 - 2026.3.3](https://github.com/mussonindustrial/embr/releases/tag/releases%2F8.1%2F2026.3.3)  
[Embr v8.3 - 2026.3.3](https://github.com/mussonindustrial/embr/releases/tag/releases%2F8.3%2F2026.3.3)

This release includes a scripting function for submitting functions to a Perspective session's queue:

`system.perspective.invokeOnQueue(function, [delay], [scope], [sessionId], [pageId])`

#### Parameters

- **function** `(required)`  
A function that will be called with a single parameter:

- **delay** `(optional)`  
Time in milliseconds to wait before invoking the function.

- **scope** `(optional)`  
Controls the lifecycle of the function relative to Perspective objects. Default is `'view'`.

- **sessionId** `(optional)`  
The target session ID.

- **pageId** `(optional)`  
The target page ID.

## Examples

### Delayed Execution

```python
def myFunction(scope):
    system.perspective.print("Running after 5 seconds. Neat.")

system.perspective.invokeOnQueue(myFunction, 5000) # default scope='view'

```

### Incrementing Counter

This example counts to 50 using view custom properties.

```python
def doThing(scope):
	if self.view.custom.count < 50:
		self.view.custom.count += 1
		self.view.custom.text = 'Counting: %d' % self.view.custom.count
		system.perspective.invokeOnQueue(doThing, 100)
	else:
		self.view.custom.text = "Done!"
	
self.view.custom.count = 0
self.view.custom.text = "Waiting to start...."
system.perspective.invokeOnQueue(doThing, 1000)

```

### Incrementing Counters (across all sessions)

This example counts to 50 using session custom properties. The functions will be run across all client sessions using `scope='session'` and `sessionId` parameters.

```python
def makeHandlers(sessionId):
    def doThing(scope):
        if scope.custom.count < 50:
            scope.custom.count += 1
            scope.custom.text = scope.custom.count
            system.perspective.invokeOnQueue(doThing, 100, scope='session', sessionId=sessionId)
        else:
            scope.custom.text = "Done!"
	
    def setup(scope):
        scope.custom.count = 0
        scope.custom.text = "Waiting to start...."
        system.perspective.invokeOnQueue(doThing, scope='session', sessionId=sessionId)
	
    return setup
	
	
sessions = system.perspective.getSessionInfo()
	
for session in sessions:
	# Simple way to filter out designer sessions
    if len(session.id) < 36:
        continue
	
    setup = makeHandlers(session.id)
    system.perspective.invokeOnQueue(setup, 1000, scope='session', sessionId=session.id)

```

## New Sponsors

Big thanks to both @David_Stone and @andrew.budaiev for sponsoring this project!  
If you're interested in contributing, check us out on [GitHub Sponsors.](https://github.com/sponsors/mussonindustrial)

---

_[View the full topic](https://forum.inductiveautomation.com/t/musson-industrials-embr-periscope-module/99047)._
