Note
Go to the end to download the full example code.
Nodes mirroring#
Showcases how pyaseba.client.Node mirrors local Aseba events
and exposes local Aseba functions to Python.
from pyaseba.client import Node
from pyaseba.client.node import EventSpec, MirroringConfig
import time
When specialized, py:class:pyaseba.client.Node may expose local Aseba events and functions of the remote node to Python by loading and running a custom Aseba script.
In particular, they:
Define user events that mirror local events. Each time a (remote) local event is emitted, the user event is forwarded to the client, together with a list of variables. This keeps the value of the Aseba variables in sync. Moreover, local events can be awaited using
pyaseba.client.Node.wait().Define user events to call remote native functions. For example, a native function f that takes an input of size 2, is exposed by a user event
call_fthat takes a size 2 payload. Users can trigger a remote function call usingpyaseba.client.Node.call().
In this example, the node mirrors local event (event), synchronizing the value
of variable counter (which is incremented by the remote node just before emitting a
the event) and exposes the Aseba function square, which sets the Aseba variable value
to the square of the function argument.
class MySimpleNode(Node):
mirroring_config = MirroringConfig(
events={"event": EventSpec(variables=["counter"])},
function_include=["square"])
node = MySimpleNode(cached=True)
node.connect(target="tcp:port=33333", start_mirroring=True)
True
The node has loaded the Aseba script, created from the class specification.
print(node.script)
var temp
onevent event
emit event_event [counter]
onevent call_square
if id == args[0] then
call square(args[1:1])
end
It mirrors local functions
print(node.mirrored_functions)
['square']
which we can call using
node.call("square", 3)
Let us verify that this indeed sets value to
the square of 3. As the value is not synchronized,
we need to query it explicitly.
print(node.get("value", cached=False))
2
It also mirrors local events
print(node.mirrored_events)
['event']
which we can wait for.
As the node is increasing the counter variable each time, we expect to see it
reflected in the counter attribute.
counter = 26
counter = 27
counter = 28
counter = 29
counter = 30
We can also define callbacks for (mirrored) local events, like
def cb(node: MySimpleNode) -> None:
print(f'counter = {node.get("counter")}')
node.set_callback("event", cb)
Sleeping for a while should get the callback called several times
time.sleep(1)
counter = 31
counter = 32
counter = 33
counter = 34
counter = 35
counter = 36
counter = 37
counter = 38
counter = 39
counter = 40
node.close(reset=True)
Total running time of the script: (0 minutes 2.020 seconds)