Connecting to a robot¶
Code that drives a robot runs in one of two places: on your own machine, reaching the robot over the
network, or on the robot itself, as a program the robot executes. Both use the same
Nate client and the same API. What differs is where the client gets its
address and its credentials.
From a remote host¶
Address and credentials¶
The robot is reached by its IP address or by a name, such as the mDNS name it announces on the local network. The API is served over HTTPS on port 8443 and the event broker over MQTTS on port 8883.
Logging in takes the username and password of a user of the robot, both required. There is no API key to pass instead: the client logs in with the credentials and obtains a session token on its own.
1 from pyniryo_nate import Nate
2
3 with Nate(hostname="10.10.10.10", login=("user", "secret")) as nate:
4 print(nate.device.get_identity())
The same client is configured from the environment when the constructor is given nothing:
export NATE_HOSTNAME=10.10.10.10
export NATE_USERNAME=user
export NATE_PASSWORD=secret
1 from pyniryo_nate import Nate
2
3 with Nate() as nate:
4 print(nate.device.get_identity())
Warning
An environment variable takes precedence over the constructor argument. With NATE_HOSTNAME set,
Nate(hostname="10.10.10.11") still connects to the robot named by the variable. A process that
drives several robots must leave NATE_HOSTNAME unset and pass each address to the constructor.
What the constructor does¶
The constructor returns a client that is ready to use, or raises. Before it returns it:
opens a TLS connection and checks that the robot is a Niryo robot, and the expected one when a device ID is given, see Trust and identity;
logs in and obtains a session token;
checks that the identity the API reports matches the certificate;
connects to the event broker, which carries the robot state and the subscriptions.
The session token expires after NATE_TOKEN_VALIDITY, one day by default. The client renews it in
the background for as long as it lives, so a long-running process never has to log in again.
Trust and identity¶
Every connection is encrypted. The robot presents a certificate signed by the Niryo certificate
authority, whose root ships with the package, so trusting a Niryo robot needs no setup. A robot whose
certificate is signed by anyone else is refused with TlsError.
To trust another root as well, point NATE_CA_FILE at a PEM file holding it.
Optional: The robot is identified by the device ID written in its certificate. Pass the expected one and any other robot at that address is refused before a credential is sent:
1 nate = Nate(hostname="10.10.10.10", login=("user", "secret"), device_id="a1b2c3d")
Without an expected device ID, the first robot reached binds the client for its lifetime: every later
connection, the event broker included, must come from that same robot.
get_identity() reports the device ID of the robot in hand, to
pin it the next time.
Errors¶
The constructor raises:
ValueErrorwhen the username or the password is missing, before anything is sent;TlsErrorwhen the certificate is not trusted or names another robot than the expected one;TransportErrorwhen the robot cannot be reached, after the retries configured byNATE_RETRYandNATE_RETRY_DELAY_FACTOR, or does not answer withinNATE_HTTP_TIMEOUT;ClientErrorwith astatus_codeof 401 when the robot refuses the credentials.
1 from pyniryo_nate import Nate
2 from pyniryo_nate.exceptions import ClientError, TlsError, TransportError
3
4 try:
5 nate = Nate(hostname="10.10.10.10", login=("user", "secret"))
6 except TlsError as error:
7 print(f"not the robot expected, or not a Niryo robot: {error}")
8 except TransportError as error:
9 print(f"robot unreachable: {error}")
10 except ClientError as error:
11 if error.status_code == 401:
12 print("wrong username or password")
13 else:
14 raise
Environment variables¶
Variable |
Meaning |
|---|---|
|
Address of the robot, default |
|
Credentials of a user of the robot. |
|
Device ID of the expected robot. |
|
PEM file holding extra roots to trust, on top of the Niryo root shipped with the package. |
|
Ports of the API and of the event broker, default |
|
Seconds to wait for an API answer, default |
|
How many times a failed connection is retried, default |
|
Lifetime of the session token, default |
As a program run by the robot¶
A program is a Python file that the robot stores and runs. Programs are run from Niryo
Studio, where the Programming panel of a project holds them and Run starts one on the robot. They can
also be uploaded and started from the client, with create()
and execute(). pyniryo-nate is installed in the runtime
that executes them.
Connecting from the program¶
Inside the program, the hostname and login provided in the constructor are ignored:
1 from pyniryo_nate import Nate
2 from pyniryo_nate.models import Joints
3
4 with Nate() as nate:
5 for _ in range(3):
6 nate.robot.move(Joints(0, 0, 0, 0, 0, 0)).wait()
7 nate.robot.move(Joints(0.5, 0, 0, 0, 0, 0)).wait()
The robot provides everything the client needs: its own address and ports, the certificate to trust, and an execution token that identifies this run. The client sends that token as its bearer credential on both transports, with no login and no renewal. No username or password is involved, and the program must not carry any. The token is only valid for that run and only while it is running or paused, so a program cannot act on the robot after it has ended, and the file holds nothing worth protecting. With the token, the moves of the program go through in automatic mode, where a remote client is refused, see Direct control.
Warning
An execution started from the client with an environment overrides the variables the robot
sets for the program, the NATE_* ones included. NATE_USERNAME and NATE_PASSWORD both
set there are the one thing that takes precedence over the execution token: the program then logs
in as that user, which is how it is redirected to another robot, and only on purpose.
Running the same file from your machine¶
A program built with Nate() runs unchanged on your machine once NATE_HOSTNAME,
NATE_USERNAME and NATE_PASSWORD are set, which is how a program is developed before being
uploaded. Run that way it is a remote client like any other: its moves need the key selector on
manual, and it holds nothing.