Script
Script node allows users to run custom Python scripts on the device. Due to the computational resource constraints, script node shouldn't be used for heavy computing (eg. image manipulation/CV), but for managing the flow of the pipeline (business logic). Example use cases would be controlling nodes like ImageManip, ColorCamera, SpatialLocationCalculator, decoding NeuralNetwork results, or interfacing with GPIOs. For debugging scripts, we suggest script_logging.How to place it
Python
C++
Python
Python
1pipeline = dai.Pipeline()
2script = pipeline.create(dai.node.Script)
Inputs and Outputs
Users can define as many inputs and outputs as they need. Inputs and outputs can be any components_messages type.Usage
Python
C++
Python
Python
1script = pipeline.create(dai.node.Script)
2script.setScript("""
3 import time
4 import marshal
5 num = 123
6 node.warn(f"Number {num}") # Print to host
7 x = [1, "Hello", {"Foo": "Bar"}]
8 x_serial = marshal.dumps(x)
9 b = Buffer(len(x_serial))
10 while True:
11 time.sleep(1)
12 b.setData(x_serial)
13 node.io['out'].send(b)
14""")
15script.outputs['out'].link(xout.input)
16
17# ...
18# After initializing the device, enable log levels
19device.setLogLevel(dai.LogLevel.WARN)
20device.setLogOutputLevel(dai.LogLevel.WARN)
Interfacing with GPIOs
In the script node you can interface with GPIOs of the VPU using module GPIO. Currently supported functions are:Python
1# Module
2import GPIO
3
4# General
5GPIO.setup(gpio, dir, pud, exclusive)
6GPIO.release(gpio)
7GPIO.write(gpio, value)
8GPIO.read(gpio)
9
10# Interrupts
11GPIO.waitInterruptEvent(gpio = -1) # blocks until any interrupt or interrupt by specified gpio is fired. Interrupts with callbacks are ignored here
12GPIO.hasInterruptEvent(gpio = -1) # returns whether interrupt happened on any or specified gpio. Interrupts with callbacks are ignored here
13GPIO.setInterrupt(gpio, edge, priority, callback = None) # adds interrupt to specified pin
14GPIO.clearInterrupt(gpio) # clears interrupt of specified pin
15
16# PWM
17GPIO.setPwm(gpio, highCount, lowCount, repeat=0) # repeat == 0 means indefinite
18GPIO.enablePwm(gpio, enable)
19
20# Enumerations
21GPIO.Direction: GPIO.IN, GPIO.OUT
22GPIO.State: GPIO.LOW, GPIO.HIGH
23GPIO.PullDownUp: GPIO.PULL_NONE, GPIO.PULL_DOWN, GPIO.PULL_UP
24GPIO.Edge: GPIO.RISING, GPIO.FALLING, GPIO.LEVEL_HIGH, GPIO.LEVEL_LOW
Python
1import GPIO
2MX_PIN = 40
3
4ret = GPIO.setup(MX_PIN, GPIO.OUT, GPIO.PULL_DOWN)
5toggleVal = True
6
7while True:
8 data = node.io['in'].get() # Wait for a message from the host computer
9
10 node.warn('GPIO toggle: ' + str(toggleVal))
11 toggleVal = not toggleVal
12 ret = GPIO.write(MX_PIN, toggleVal) # Toggle the GPIO
Time synchronization
Script node has access to both device (internal) clock and also synchronized host clock. Host clock is synchronized with device clock at below 2.5ms precision at 1σ, Host clock syncing.Python
1import time
2interval = 60
3ctrl = CameraControl()
4ctrl.setCaptureStill(True)
5previous = 0
6while True:
7 time.sleep(0.001)
8
9 tnow_full = Clock.nowHost() # Synced clock with host
10 # Clock.now() -> internal/device clock
11 # Clock.offsetToHost() -> Offset between internal/device clock and host clock
12
13 now = tnow_full.seconds
14 if now % interval == 0 and now != previous:
15 previous = now
16 node.warn(f'{tnow_full}')
17 node.io['out'].send(ctrl)
Using DepthAI Messages
The depthai module is implicitly imported to the script node. You can create new depthai messages and assign data to it, for example:Python
1buf = Buffer(100) # Assign 100 bytes to the Buffer message
2
3# Create CameraControl message, set manual focus
4control = CameraControl()
5control.setManualFocus(100)
6
7imgFrame = ImgFrame(300*300*3) # Buffer with 300x300x3 bytes
Available modules and libraries
Available modulesText
1"posix", "errno", "pwd", "_sre", "_codecs", "_weakref", "_functools", "_operator",
2"_collections", "_abc", "itertools", "atexit", "_stat", "time", "_datetime", "math",
3"_thread", "_io", "_symtable", "marshal", "_ast", "gc", "_warnings", "_string", "_struct"
Text
1"binascii", "_random", "_socket", "_md5", "_sha1", "_sha256", "_sha512", "select",
2"array", "unicodedata"
Text
1"__main__", "_collections_abc", "_frozen_importlib", "_frozen_importlib_external",
2"_sitebuiltins", "abc", "codecs", "datetime", "encodings", "encodings.aliases",
3"encodings.ascii", "encodings.latin_1", "encodings.mbcs", "encodings.utf_8", "genericpath",
4"io", "os", "posixpath", "site", "stat", "threading", "types", "struct", "copyreg",
5"reprlib", "operator", "keyword", "heapq", "collections", "functools", "sre_constants",
6"sre_parse", "sre_compile", "enum", "re", "json", "json.decoder", "json.encoder",
7"json.scanner", "textwrap"
Text
1"http", "http.client", "http.server", "html", "mimetypes", "copy", "shutil", "fnmatch",
2"socketserver", "contextlib", "email", "email._encoded_words", "email._header_value_parser",
3"email._parseaddr", "email._policybase", "email.base64mime", "email.charset",
4"email.contentmanager", "email.encoders", "email.errors", "email.feedparser",
5"email.generator", "email.header", "email.headerregistry", "email.iterators", "email.message",
6"email.parser", "email.policy", "email.quoprimime", "email.utils", "string", "base64",
7"quopri", "random", "warnings", "bisect", "hashlib", "logging", "traceback", "linecache",
8"socket", "token", "tokenize", "weakref", "_weakrefset", "collections.abc", "selectors",
9"urllib", "urllib.parse", "calendar", "locale", "uu", "encodings.idna", "stringprep"
Python
1script = pipeline.create(dai.node.Script)
2script.setProcessor(dai.ProcessorType.LEON_CSS)
Examples of functionality
- Script camera control - Controlling the camera
- Script get local IP - Get local IP
- Script HTTP client - Send HTTP request
- Script TCP streaming - TCP communication from within Script node, either in host or client mode
- Script MQTT publishing - MQTT publishing from within Script node
- Script HTTP server - still image over HTTP
- Script MJPEG server - MJPEG video stream over HTTP
- Script NNData example - Constructs NNData
- Triangulation experiment
- Movenet decoding (edge mode) - A bit more complex example by geaxgx
Reference
class
depthai.node.Script(depthai.Node)
method
getProcessor(self) -> depthai.ProcessorType: depthai.ProcessorType
Get on which processor the script should run Returns: Processor type - Leon CSS or Leon MSS
method
getScriptName(self) -> str: str
Get the script name in utf-8. When name set with setScript() or setScriptPath(), returns that name. When script loaded with setScriptPath() with name not provided, returns the utf-8 string of that path. Otherwise, returns "<script>" Returns: std::string of script name in utf-8
method
setProcessor(self, arg0: depthai.ProcessorType)
Set on which processor the script should run Parameter ``type``: Processor type - Leon CSS or Leon MSS
method
method
property
property
Need assistance?
Head over to Discussion Forum for technical support or any other questions you might have.