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 node logging.
How to place it¶
pipeline = dai.Pipeline()
script = pipeline.create(dai.node.Script)
dai::Pipeline pipeline;
auto script = pipeline.create<dai::node::Script>();
Inputs and Outputs¶
inputs[] ┌──────────────┐ outputs[]
---------►│ ├-----------►
---------►│ ├-----------►
... │ Script | ...
... │ │ ...
---------►│ ├-----------►
└──────────────┘
Users can define as many inputs and outputs as they need. Inputs and outputs can be any Message type.
Usage¶
script = pipeline.create(dai.node.Script)
script.setScript("""
import time
import marshal
num = 123
node.warn(f"Number {num}") # Print to host
x = [1, "Hello", {"Foo": "Bar"}]
x_serial = marshal.dumps(x)
b = Buffer(len(x_serial))
while True:
time.sleep(1)
b.setData(x_serial)
node.io['out'].send(b)
""")
script.outputs['out'].link(xout.input)
# ...
# After initializing the device, enable log levels
device.setLogLevel(dai.LogLevel.WARN)
device.setLogOutputLevel(dai.LogLevel.WARN)
auto script = pipeline.create<dai::node::Script>();
script->setScript(R"(
import time
import marshal
num = 123
node.warn(f"Number {num}") # Print to host
x = [1, "Hello", {"Foo": "Bar"}]
x_serial = marshal.dumps(x)
b = Buffer(len(x_serial))
while True:
time.sleep(1)
b.setData(x_serial)
node.io['out'].send(b)
)");
script->outputs["out"].link(xout->input);
// ...
// After initializing the device, enable log levels
device.setLogLevel(dai::LogLevel.WARN);
device.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:
# Module
import GPIO
# General
GPIO.setup(gpio, dir, pud, exclusive)
GPIO.release(gpio)
GPIO.write(gpio, value)
GPIO.read(gpio)
# Interrupts
GPIO.waitInterruptEvent(gpio = -1) # blocks until any interrupt or interrupt by specified gpio is fired. Interrupts with callbacks are ignored here
GPIO.hasInterruptEvent(gpio = -1) # returns whether interrupt happened on any or specified gpio. Interrupts with callbacks are ignored here
GPIO.setInterrupt(gpio, edge, priority, callback = None) # adds interrupt to specified pin
GPIO.clearInterrupt(gpio) # clears interrupt of specified pin
# PWM
GPIO.setPwm(gpio, highCount, lowCount, repeat=0) # repeat == 0 means indefinite
GPIO.enablePwm(gpio, enable)
# Enumerations
GPIO.Direction: GPIO.IN, GPIO.OUT
GPIO.State: GPIO.LOW, GPIO.HIGH
GPIO.PullDownUp: GPIO.PULL_NONE, GPIO.PULL_DOWN, GPIO.PULL_UP
GPIO.Edge: GPIO.RISING, GPIO.FALLING, GPIO.LEVEL_HIGH, GPIO.LEVEL_LOW
Here’s an example of toggling GPIO pin 40 inside Script node from the host (via XLinkIn). On OAK-SoM-Pro, GPIO 40 drives FSYNC signal for both 4-lane cameras, and we have used the code below for this exact reason.
import GPIO
MX_PIN = 40
ret = GPIO.setup(MX_PIN, GPIO.OUT, GPIO.PULL_DOWN)
toggleVal = True
while True:
data = node.io['in'].get() # Wait for a message from the host computer
node.warn('GPIO toggle: ' + str(toggleVal))
toggleVal = not toggleVal
ret = GPIO.write(MX_PIN, toggleVal) # Toggle the GPIO
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:
buf = Buffer(100) # Assign 100 bytes to the Buffer message
# Create CameraControl message, set manual focus
control = CameraControl()
control.setManualFocus(100)
imgFrame = ImgFrame(300*300*3) # Buffer with 300x300x3 bytes
Available modules and libraries¶
"posix", "errno", "pwd", "_sre", "_codecs", "_weakref", "_functools", "_operator",
"_collections", "_abc", "itertools", "atexit", "_stat", "time", "_datetime", "math",
"_thread", "_io", "_symtable", "marshal", "_ast", "gc", "_warnings", "_string", "_struct"
"binascii", "_random", "_socket", "_md5", "_sha1", "_sha256", "_sha512", "select",
"array", "unicodedata"
"__main__", "_collections_abc", "_frozen_importlib", "_frozen_importlib_external",
"_sitebuiltins", "abc", "codecs", "datetime", "encodings", "encodings.aliases",
"encodings.ascii", "encodings.latin_1", "encodings.mbcs", "encodings.utf_8", "genericpath",
"io", "os", "posixpath", "site", "stat", "threading", "types", "struct", "copyreg",
"reprlib", "operator", "keyword", "heapq", "collections", "functools", "sre_constants",
"sre_parse", "sre_compile", "enum", "re", "json", "json.decoder", "json.encoder",
"json.scanner", "textwrap"
"http", "http.client", "http.server", "html", "mimetypes", "copy", "shutil", "fnmatch",
"socketserver", "contextlib", "email", "email._encoded_words", "email._header_value_parser",
"email._parseaddr", "email._policybase", "email.base64mime", "email.charset",
"email.contentmanager", "email.encoders", "email.errors", "email.feedparser",
"email.generator", "email.header", "email.headerregistry", "email.iterators", "email.message",
"email.parser", "email.policy", "email.quoprimime", "email.utils", "string", "base64",
"quopri", "random", "warnings", "bisect", "hashlib", "logging", "traceback", "linecache",
"socket", "token", "tokenize", "weakref", "_weakrefset", "collections.abc", "selectors",
"urllib", "urllib.parse", "calendar", "locale", "uu", "encodings.idna", "stringprep"
The difference between module and library is that module is a precompiled C source with Python bindings, whereas library is Python source code packed into a library and precompiled into Python bytecode (before loaded into our Firmware).
Networking/protocol modules/libraries that are available on the LEON_CSS can only be used on OAK POE device. You can specify on which processor the script will run, eg. for LEON_CSS:
script = pipeline.create(dai.node.Script)
script.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
Movenet decoding (edge mode) - A bit more complex example by geaxgx
Reference¶
-
class
depthai.node.
Script
-
class
Connection
Connection between an Input and Output
-
class
Id
Node identificator. Unique for every node on a single Pipeline
-
Properties
alias of
depthai.ScriptProperties
-
getAssetManager
(*args, **kwargs) Overloaded function.
getAssetManager(self: depthai.Node) -> depthai.AssetManager
Get node AssetManager as a const reference
getAssetManager(self: depthai.Node) -> depthai.AssetManager
Get node AssetManager as a const reference
-
getInputRefs
(*args, **kwargs) Overloaded function.
getInputRefs(self: depthai.Node) -> List[depthai.Node.Input]
Retrieves reference to node inputs
getInputRefs(self: depthai.Node) -> List[depthai.Node.Input]
Retrieves reference to node inputs
-
getInputs
(self: depthai.Node) → List[depthai.Node.Input] Retrieves all nodes inputs
-
getName
(self: depthai.Node) → str Retrieves nodes name
-
getOutputRefs
(*args, **kwargs) Overloaded function.
getOutputRefs(self: depthai.Node) -> List[depthai.Node.Output]
Retrieves reference to node outputs
getOutputRefs(self: depthai.Node) -> List[depthai.Node.Output]
Retrieves reference to node outputs
-
getOutputs
(self: depthai.Node) → List[depthai.Node.Output] Retrieves all nodes outputs
-
getParentPipeline
(*args, **kwargs) Overloaded function.
getParentPipeline(self: depthai.Node) -> depthai.Pipeline
getParentPipeline(self: depthai.Node) -> depthai.Pipeline
-
getProcessor
(self: depthai.node.Script) → depthai.ProcessorType Get on which processor the script should run
- Returns
Processor type - Leon CSS or Leon MSS
-
getScriptName
(self: depthai.node.Script) → 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
-
property
id
Id of node
-
setProcessor
(self: depthai.node.Script, arg0: depthai.ProcessorType) → None Set on which processor the script should run
- Parameter
type
: Processor type - Leon CSS or Leon MSS
- Parameter
-
setScript
(*args, **kwargs) Overloaded function.
setScript(self: depthai.node.Script, script: str, name: str = ‘’) -> None
Sets script data to be interpreted
- Parameter
script
: Script string to be interpreted
- Parameter
name
: Optionally set a name of this script
setScript(self: depthai.node.Script, data: List[int], name: str = ‘’) -> None
Sets script data to be interpreted
- Parameter
data
: Binary data that represents the script to be interpreted
- Parameter
name
: Optionally set a name of this script
-
setScriptPath
(*args, **kwargs) Overloaded function.
setScriptPath(self: depthai.node.Script, arg0: Path, arg1: str) -> None
Specify local filesystem path to load the script
- Parameter
path
: Filesystem path to load the script
- Parameter
name
: Optionally set a name of this script, otherwise the name defaults to the path
setScriptPath(self: depthai.node.Script, path: Path, name: str = ‘’) -> None
Specify local filesystem path to load the script
- Parameter
path
: Filesystem path to load the script
- Parameter
name
: Optionally set a name of this script, otherwise the name defaults to the path
-
class
-
class
dai::node
::
Script
: public dai::NodeCRTP<Node, Script, ScriptProperties>¶ Public Functions
-
void
setScriptPath
(const dai::Path &path, const std::string &name = "")¶ Specify local filesystem path to load the script
- Parameters
path
: Filesystem path to load the scriptname
: Optionally set a name of this script, otherwise the name defaults to the path
-
void
setScript
(const std::string &script, const std::string &name = "")¶ Sets script data to be interpreted
- Parameters
script
: Script string to be interpretedname
: Optionally set a name of this script
-
void
setScript
(const std::vector<std::uint8_t> &data, const std::string &name = "")¶ Sets script data to be interpreted
- Parameters
data
: Binary data that represents the script to be interpretedname
: Optionally set a name of this script
-
dai::Path
getScriptPath
() const¶ Get filesystem path from where script was loaded.
- Return
dai::Path from where script was loaded, otherwise returns empty path
-
std::string
getScriptName
() const¶ 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>”
- Return
std::string of script name in utf-8
-
void
setProcessor
(ProcessorType type)¶ Set on which processor the script should run
- Parameters
type
: Processor type - Leon CSS or Leon MSS
-
ProcessorType
getProcessor
() const¶ Get on which processor the script should run
- Return
Processor type - Leon CSS or Leon MSS
Public Members
Public Static Attributes
-
static constexpr const char *
NAME
= "Script"¶
-
void
Got questions?
We’re always happy to help with code or other questions you might have.