Dies ist die Beschreibung der Rust API Bindings für die IP Connection. Die IP Connection kümmert sich um die Kommunikation zwischen einem Brick Daemon oder einer WIFI/Ethernet Extension. Bevor Bricks und Bricklets über deren API angesprochen werden können muss eine IP Connection erzeugt und die TCP/IP Verbindung hergestellt werden.
Eine Installationanleitung für die Rust API Bindings ist Teil deren allgemeine Beschreibung.
Der folgende Beispielcode ist Public Domain (CC0 1.0).
Download (example_enumerate.rs)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | use std::{error::Error, io, thread};
use tinkerforge::ip_connection::{EnumerateResponse, EnumerationType, IpConnection};
const HOST: &str = "localhost";
const PORT: u16 = 4223;
fn print_enumerate_response(response: &EnumerateResponse) {
println!("UID: {}", response.uid);
println!("Enumeration Type: {:?}", response.enumeration_type);
if response.enumeration_type == EnumerationType::Disconnected {
println!("");
return;
}
println!("Connected UID: {}", response.connected_uid);
println!("Position: {}", response.position);
println!("Hardware Version: {}.{}.{}", response.hardware_version[0], response.hardware_version[1], response.hardware_version[2]);
println!("Firmware Version: {}.{}.{}", response.firmware_version[0], response.firmware_version[1], response.firmware_version[2]);
println!("Device Identifier: {}", response.device_identifier);
println!("");
}
fn main() -> Result<(), Box<dyn Error>> {
let ipcon = IpConnection::new(); // Create IP connection
ipcon.connect((HOST, PORT)).recv()??; // Connect to brickd
let receiver = ipcon.get_enumerate_callback_receiver();
// Spawn thread to react to enumerate callback messages.
// This thread must not be terminated or joined,
// as it will end when the IP connection (and the receiver's sender) is dropped.
thread::spawn(move || {
for response in receiver {
print_enumerate_response(&response);
}
});
// Trigger Enumerate
ipcon.enumerate();
println!("Press enter to exit.");
let mut _input = String::new();
io::stdin().read_line(&mut _input)?;
ipcon.disconnect();
Ok(())
}
|
Download (example_authenticate.rs)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | use std::{error::Error, io, thread};
use tinkerforge::ip_connection::{ConnectReason, EnumerateResponse, EnumerationType, IpConnection, IpConnectionRequestSender};
const HOST: &str = "localhost";
const PORT: u16 = 4223;
const SECRET: &str = "My Authentication Secret!";
fn authenticate(reason: ConnectReason, request_sender: &mut IpConnectionRequestSender) {
match reason {
ConnectReason::Request => println!("Connected by request"),
ConnectReason::AutoReconnect => println!("Auto-Reconnected"),
}
// Authenticate first...
match request_sender.authenticate(SECRET) {
Ok(rx) => {
if let Ok(_) = rx.recv() {
println!("Authentication succeded");
// ...reenable auto reconnect mechanism, as described below...
request_sender.set_auto_reconnect(true);
// ...then trigger enumerate
request_sender.enumerate();
} else {
println!("Authentication request sent, but got no response. Maybe your secret is wrong?")
}
}
Err(e) => println!("Could not authenticate: {}", e),
}
}
fn print_enumerate_response(response: &EnumerateResponse) {
println!("UID: {}", response.uid);
println!("Enumeration Type: {:?}", response.enumeration_type);
if response.enumeration_type == EnumerationType::Disconnected {
println!("");
return;
}
println!("Connected UID: {}", response.connected_uid);
println!("Position: {}", response.position);
println!("Hardware Version: {}.{}.{}", response.hardware_version[0], response.hardware_version[1], response.hardware_version[2]);
println!("Firmware Version: {}.{}.{}", response.firmware_version[0], response.firmware_version[1], response.firmware_version[2]);
println!("Device Identifier: {}", response.device_identifier);
println!("");
}
fn main() -> Result<(), Box<dyn Error>> {
let mut ipcon = IpConnection::new(); // Create IP connection
// Disable auto reconnect mechanism, in case we have the wrong secret. If the authentication is successful, reenable it.
ipcon.set_auto_reconnect(false);
let connect_receiver = ipcon.get_connect_callback_receiver();
// Spawn thread to react to connect callback messages.
// This thread must not be terminated or joined,
// as it will end when the IP connection (and the receiver's sender) is dropped.
let mut request_sender = ipcon.get_request_sender();
thread::spawn(move || {
for reason in connect_receiver {
authenticate(reason, &mut request_sender)
}
});
// Get Enumerate Receiver
let enumerate_receiver = ipcon.get_enumerate_callback_receiver();
// Spawn thread to react to enumerate events. This thread must not be terminated or joined,
// as it will end when the IP connection (and the receiver's sender) is dropped.
thread::spawn(move || {
for response in enumerate_receiver {
print_enumerate_response(&response);
}
});
ipcon.connect((HOST, PORT)).recv()??; // Connect to brickd
println!("Press enter to exit.");
let mut _input = String::new();
io::stdin().read_line(&mut _input)?;
ipcon.disconnect();
Ok(())
}
|
Die IPConnection ist im Modul tinkerforge::ip_connection
definiert.
IpConnection::
new
() → IpConnection¶Erzeugt ein IP Connection Objekt das verwendet werden kann um die verfügbar Geräte zu enumerieren. Es wird auch für den Konstruktor von Bricks und Bricklets benötigt.
IpConnection::
get_request_sender
(&self) → IpConnectionRequestSender¶Die IP-Connection kann nicht mit anderen Threads geteilt werden. Um in solchen dennoch die Funktionalität der IP-Connection nutzen zu können, kann mit dieser Methode ein IP-Connection-Request-Sender erstellt werden, der die selben Methoden zur Verfügung stellt. Besitzer der Verbindung bleibt die IP-Connection, sodass die Request-Sender-Objekte beliebig erzeugt, geklont, an andere Threads übergeben und zerstört werden können.
IpConnection::
connect
<T: ToSocketAddrs>
(&self, addr: T) → Receiver<Result<(), ConnectError>>¶Erstellt eine TCP/IP Verbindung zur gegebenen addr
, die ToSocketAddrs implementiert. Zum Beispiel kann ein Tupel (host, port)
, bei dem host
ein String (eine IP-Addresse oder ein Hostname) und port
ein u16
sind, verwendet werden. Host und Port können auf einen Brick Daemon oder eine WIFI/Ethernet Extension verweisen.
Bricks/Bricklets können erst gesteuert werden, wenn die Verbindung erfolgreich aufgebaut wurde.
Gibt einen Receiver zurück, der entweder ()
oder, falls
kein Brick Daemon oder WIFI/Ethernet Extension auf dem gegebenen Host und Port
horcht, einen ConnectError
empfängt.
IpConnection::
disconnect
(&self) → Receiver<Result<(), DisconnectErrorNotConnected>>¶Trennt die TCP/IP Verbindung zum Brick Daemon oder einer WIFI/Ethernet
Extension. Gibt einen Receiver zurück, der entweder ()
oder, falls keine Verbindung bestand, einen Fehler empfängt.
IpConnection::
authenticate
(&self, secret: &str) → Result<ConvertingReceiver<()>, AuthenticateError>¶Führt einen Authentifizierungs-Handshake mit dem verbundenen Brick Daemon oder WIFI/Ethernet Extension durch. Ist der Handshake erfolgreich dann wechselt die Verbindung vom nicht-authentifizierten in den authentifizierten Zustand und die Kommunikation kann normal weitergeführt werden. Schlägt der Handshake fehl wird die Verbindung durch die Gegenseite geschlossen. Die Authentifizierung kann fehlschlagen wenn das Authentifizierungsgeheimnis nicht übereinstimmt oder Authentifizierung für den Brick Daemon oder die WIFI/Ethernet Extension nicht aktiviert ist.
Für mehr Informationen zur Authentifizierung siehe das dazugehörige Tutorial.
IpConnection::
get_connection_state
(&self) → ConnectionState¶Kann die folgenden Zustände zurückgeben:
IpConnection::
set_auto_reconnect
(&mut self, auto_reconnect_enabled: bool)¶Aktiviert oder deaktiviert Auto-Reconnect. Falls Auto-Reconnect aktiviert
ist, versucht die IP Connection eine Verbindung zum vorher angegebenen Host
und Port wieder herzustellen, falls die aktuell bestehende Verbindung verloren
geht. Auto-Reconnect greift also erst nach einem erfolgreichen Aufruf von
connect()
.
Standardwert ist true.
IpConnection::
get_auto_reconnect
(&self) → bool¶Gibt true zurück wenn Auto-Reconnect aktiviert ist und false sonst.
IpConnection::
set_timeout
(&mut self, timeout: std::time::Duration)¶Setzt den Timeout für Getter und für Setter die das Response-Expected-Flag aktiviert haben.
Standardwert ist 2500 ms.
IpConnection::
get_timeout
(&self) → std::time::Duration¶Gibt den Timeout zurück, wie er von set_timeout()
gesetzt wurde.
IpConnection::
enumerate
(&self)¶Broadcast einer Enumerierungsanfrage. Alle Bricks und Bricklets werden mit einem Enumerate Callback antworten.
Callbacks können registriert werden um über Ereignisse informiert zu werden. Die Registrierung geschieht durch das Erstellen eines Receivers für die Nachrichten des Callbacks. Empfangene Nachrichten können in einem neuen Thread asynchron verarbeitet werden:
let receiver = ipcon.get_example_callback_receiver();
// No join is needed here, as the iteration over the receiver ends when the ipcon is dropped.
thread::spawn(move || {
for value in receiver {
println!("Value: {:?}", value);
}
};
Die verfügbaren Events werden im Folgenden beschrieben.
IpConnection::
get_enumerate_callback_receiver
(&self) → ConvertingCallbackReceiver<EnumerateResponse>¶Der Event empfängt eine Struktur mit sieben Feldern:
uid
: Die UID des Bricks/Bricklets.connected_uid
: Die UID des Gerätes mit dem der Brick/das Bricklet verbunden
ist. Für ein Bricklet ist dies die UID des Bricks oder Bricklets mit dem es verbunden ist.
Für einen Brick ist es die UID des untersten Bricks im Stapel.
Der unterste Master Brick hat die Connected-UID "0". Mit diesen Informationen
sollte es möglich sein die komplette Netzwerktopologie zu rekonstruieren.position
: Für Bricks: '0' - '8' (Position in Stapel). Für Bricklets:
'a' - 'h' (Position an Brick) oder 'i' (Position des Raspberry Pi (Zero) HAT)
oder 'z' (Bricklet an Isolator Bricklet).hardware_version
: Major, Minor und Release Nummer der Hardwareversion.firmware_version
: Major, Minor und Release Nummer der Firmwareversion.device_identifier
: Eine Zahl, welche den Brick/Bricklet repräsentiert.enumeration_type
: Art der Enumerierung.Mögliche Enumerierungsarten sind:
enumerate()
). Diese Enumerierungsart kann mehrfach für das
selbe Gerät auftreten.uid
und
enumerationType
einen gültigen Wert.Es sollte möglich sein Plug-and-Play-Funktionalität mit diesem Event zu implementieren (wie es im Brick Viewer geschieht).
Die Device Identifier Werte sind hier zu finden. Es gibt auch Konstanten für diese Werte, welche nach dem folgenden Muster benannt sind:
<device-class>::DEVICE_IDENTIFIER
Zum Beispiel: :MasterBrick::DEVICE_IDENTIFIER
oder AmbientLightBricklet::DEVICE_IDENTIFIER
.
IpConnection::
get_connect_callback_receiver
(&self) → Receiver<ConnectReason>¶Dieser Event wird ausgelöst wenn die IP Connection eine Verbindung zu einem Brick Daemon oder einer WIFI/Ethernet Extension aufgebaut hat, mögliche Gründe sind:
IpConnection::
get_disconnect_callback_receiver
(&self) → Receiver<DisconnectReason>¶Dieser Event wird aufgerufen wenn die Verbindung der IP Connection zu einem Brick Daemon oder einer WIFI/Ethernet Extension getrennt wurde, mögliche Gründe sind: