Python Toolkit API Node¶
zhinst.toolkit.nodetree.node.Node(root, tree)
¶
Lazy node of a Nodetree
.
The node is implemented in a lazy way. Meaning unless operations are not performed on the node, no checks whether the node is valid or not are performed.
The child nodes of each node can be accessed in the same way than on the Nodetree, either by attribute or by item.
The core functionality of each node is the overloaded call operator. Making a call gets the value(s) for that node. Passing a value to the call operator will set that value to the node on the device. Calling a node that is not a leaf (wildcard or partial node) will return/set the value on every node that matches it (the return type will be a dictionary).
Warning
Setting a value to a non-leaf node will try to set the value of all nodes that matches that node. It should therefor be used with great care to avoid unintentional changes.
Example
nodetree.demods[0].freq() 1000 nodetree.demods[0].freq(2000) nodetree.demods[0].freq() 2000
nodetree.demods[""].freq(3000) nodetree.demods[""].freq() { '/dev1234/demods/0/freq': 3000 '/dev1234/demods/1/freq': 3000 '/dev1234/demods/2/freq': 3000 '/dev1234/demods/3/freq': 3000 }
The call operator supports the following flags:
-
deep: Flag if the set operation should be blocking until the data has arrived at the device, respectively if the get operation should return the value from the device or the cached value on the data server (if there is any). If this flag is set the operation can take significantly longer. (default = False)
For a deep get operation the timestamp from the device is returned in addition to the value (The timestamp can be None, e.g. deep gets on LabOne modules).
>>> nodetree.demods[0].freq(deep=True) (343283971893, 2000)
For a deep set the call operator will return the value acknowledged by the device. e.g. important for floating point values with a limited resolution.
>>> nodetree.demods[0].freq(29999,99999, deep=True) 3000
Warning
The deep flag does not work for wildcard nodes or non leaf nodes since they represent multiple nodes that are set in a transactional set which does not report the acknowledged values.
-
enum: Flag if enumerated values should return the enum value as string. (default = True)
-
parse: Flag if the SetParser/GetParser from the Node, if present, should be applied or not (default = True).
The parsers are hard coded lambda functions provided not directly by LabOne but need to be set manually (e.g. toolkit adds these for a selected set of nodes). The Lambda function gets called right before/after the API call to LabOne. Usually they are used to add additional limitations and improve error reporting but in theory they can be used for anything.
To add a parser to a node use the
NodeTree.update_node
function.>>> nodetree.update_node( "/dev1234/demods/0/freq", { "GetParser": lambda v: print(f"got {v} from LabOne") return v, "SetParser": lambda v: print(f"set {v} to LabOne") return v, }, )
In addition to the call operator the following magic methods are implemented:
- contains
>>> "freq" in nodetree.demods[0] True
- iter
>>> for node, info in nodetree.demods["*"].freq
- eq
>>> nodetree.demods[0].freq == nodetree.demods["*/freq"]
- len (only implemented for list like nodes)
>>> len(nodetree.demods) 4
- bool test if the node is a existing node
>>> if nodetree.demods[0].freq: ...
- hash (e.g. necessary to be able to use nodes as key in dictionaries)
Parameters:
Name | Type | Description | Default |
---|---|---|---|
root |
NodeTree
|
Root of the nodetree. |
required |
tree |
tuple
|
Tree (node path as tuple) of the current node. |
required |
node_info: NodeInfo
property
¶
raw_tree: tuple[str, ...]
property
¶
root: NodeTree
property
¶
child_nodes(*, recursive=False, leavesonly=False, settingsonly=False, streamingonly=False, subscribedonly=False, basechannelonly=False, excludestreaming=False, excludevectors=False)
¶
Generator for all child nodes that matches the filters.
If the nodes does not contain any child nodes the generator will only contain the node itself (if it matches the filters).
Warning
The Data Server supports only the asterisk wildcard. For all other wildcards the matching child nodes can be generated manually within the nodetree.
Enabling additional flags how ever require that each node that
matches the wildcard needs to be checked in a separate request by
the Data Server which can cause a severe latency. Therefore one
needs to enable the full_wildcard
flag in order to support the
manual generation of the matching child nodes.
Example
child_nodes = nodetree.demods[0].child_nodes() next(child_nodes) /dev1234/demods/0/freq
Parameters:
Name | Type | Description | Default |
---|---|---|---|
recursive |
bool
|
Returns the nodes recursively (default: False) |
False
|
leavesonly |
bool
|
Returns only nodes that are leaves, which means they are at the outermost level of the tree (default: False). |
False
|
settingsonly |
bool
|
Returns only nodes which are marked as setting (default: False). |
False
|
streamingonly |
bool
|
Returns only streaming nodes (default: False). |
False
|
subscribedonly |
bool
|
Returns only subscribed nodes (default: False). |
False
|
basechannelonly |
bool
|
Return only one instance of a node in case of multiple channels (default: False). |
False
|
excludestreaming |
bool
|
Exclude streaming nodes (default: False). |
False
|
excludevectors |
bool
|
Exclude vector nodes (default: False). |
False
|
Returns:
Type | Description |
---|---|
None
|
Generator of all child nodes that match the filters |
get_as_event()
¶
Trigger an event for that node (its child lead nodes).
The node data is returned by a subsequent poll command.
is_child_node(child_node)
¶
is_valid()
¶
Check if the node is a valid node.
Valid node means it resolves to at least one existing node in the node tree. Meaning not only leaf nodes are valid nodes but also partial nodes and nodes containing wildcards.
Returns:
Type | Description |
---|---|
bool
|
Flag if the node is a valid node |
subscribe()
¶
Subscribe to this node (its child lead nodes).
To get data from data from the subscribed nodes use the poll command (provided by the Connection).
In order to avoid fetching old data that is still in the buffer execute a sync command before subscribing to new data streams.
unsubscribe()
¶
Unsubscribe this node (its child lead nodes).
Use this command after recording to avoid buffer overflows that may increase the latency of subsequent commands.
wait_for_state_change(value, *, invert=False, timeout=2.0, sleep_time=0.005)
¶
Waits until the node has the expected state/value.
Warning
Only supports integer nodes. (The value can either be the value or its corresponding enum value as string)
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Union[int, str, NodeEnum]
|
Expected value of the node. |
required |
invert |
bool
|
Instead of waiting for the value, the function will wait for any value except the passed value instead. Useful when waiting for value to change from existing one.(default = False) |
False
|
timeout |
float
|
Maximum wait time in seconds. (default = 2) |
2.0
|
sleep_time |
float
|
Sleep interval in seconds. (default = 0.005) |
0.005
|
Raises:
Type | Description |
---|---|
TimeoutError
|
Timeout exceeded. |
zhinst.toolkit.nodetree.helper.NodeDict(result)
¶
Bases: Mapping
Mapping of dictionary structure results.
The mapping allows to access data with both the string and the toolkit node objects.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
result |
dict[str, Any]
|
A dictionary of node/value pairs. |
required |
Example
result = device.demods["*"].enable() print(result) { '/dev1234/demods/0/enable': 0, '/dev1234/demods/1/enable': 1, } result[device.demods[0].enable] 0 result["/dev1234/demods/0/enable"] 0
to_dict()
¶
Convert the WildcardResult to a dictionary.
After conversion, Node
objects cannot be used to get items.