Device Discovery & Connection
Developer Guide
Connecting takes three steps: scan the local network and local USB bus for a device list, locate the target by serial number, address, or handedness, and let the SDK hold the connection until you close it explicitly. Python and C share the same semantics. They differ in error reporting and handle lifetime.
Device Discovery
Scan for Wuji devices connected via Ethernet on the local network or over USB:
Python
C
from wuji_sdk import SdkManager
manager = SdkManager.instance()
devices = manager.scan()
for dev in devices:
print(f"SN: {dev.sn}, Type: {dev.device_type}, Address: {dev.address}")#include "wuji_sdk.h"
wuji_init(NULL);
WujiDiscovered *devs = NULL;
size_t count = 0;
wuji_scan(&devs, &count);
for (size_t i = 0; i < count; i++) {
printf("SN: %s, Type: %s, Address: %s\n",
devs[i].serial_number, devs[i].model, devs[i].address);
}
wuji_discovered_free(devs, count); Each discovered record carries the serial number, address, and device type, so you can tell what a device is before connecting. In Python, DiscoveredDevice.device_type is a DeviceType enum (WujiGlove / WujiHand2 / WujiHand). In C, WujiDiscovered.device_id is a WujiDeviceType enum (WUJI_DEVICE_TYPE_WUJI_GLOVE / _WUJI_HAND_2 / _WUJI_HAND). Unknown and WUJI_DEVICE_TYPE_UNKNOWN mean the type was not available at scan time or isn’t recognized by this SDK build.
Network prerequisite: Ethernet devices use static IPs, not DHCP. Before scanning or connecting, set your host NIC to the same subnet (for example 192.168.1.50, avoiding the device default addresses), or the devices can’t be discovered or reached.
- Wuji Hand 2: left hand
192.168.1.110, right hand192.168.1.111— see Wuji Hand 2 SDK Reference — Device Operations for address details and how to change the IP - Wuji Glove: left hand
192.168.1.100, right hand192.168.1.101— see Wuji Glove Getting Started for setup steps - Wuji Hand: connects over USB, no network setup required
When running the SDK on macOS, allow the terminal or IDE to access the device’s local network if prompted for local network permission. If the system firewall is enabled and prompts you to allow incoming connections for the application, select Allow.
On macOS 15 or later, if you denied local network access, enable it for the terminal or IDE in System Settings › Privacy & Security › Local Network.
Connecting to a Device
device_name in all connect APIs is a local alias, used only to look up the device later and to namespace resource paths. It does not select a device and does not determine the returned handle type. The returned type is determined by the actual connected device. The name must be non-empty and must not contain / or ..
Choose a Connection Method
Pick by how many devices are currently discovered. See Auto Connect, Connect by SN, Connect by Address, Connect by USB, and Connect by Handedness:
How many devices does scan() currently find?
│
├─ exactly one ──▶ auto_connect() — works for USB and Ethernet alike
│
└─ multiple ▶ connect() with an explicit locator — sn / address / handedness are mutually exclusive
├─ sn=... — any device, most precise (filter USB devices by TransportType.Usb first)
├─ address=... — direct connect when you know the IP
└─ handedness=... — by hand side (Wuji Hand 2 / Wuji Glove)
└─ multiple same-side devices ▶ AmbiguousHandedness ▶ use sn Any method can take Connection Options to configure timeout, retries, and device sharing.
Auto Connect
auto_connect() connects to the single device currently discovered. If multiple devices are present, the call fails because the target is ambiguous. Use connect() to disambiguate in that case:
glove = manager.auto_connect(device_name="glove")
print(f"Connected: {glove.serial_number}") C has no equivalent. Call wuji_scan(), confirm the list holds exactly one record, then take its serial_number and follow Connect by SN.
Connect by SN
Connect to a specific device by serial number:
Python
C
glove = manager.connect(sn="WG1JA00XXXXXXXXX", device_name="glove")WujiConnectTarget target = {
.kind = WUJI_CONNECT_TARGET_KIND_SN,
.value = "WG1JA00XXXXXXXXX",
};
WujiDevice *glove = NULL;
if (wuji_connect(&target, "glove", NULL, &glove) != WUJI_STATUS_OK) {
fprintf(stderr, "connect failed: %s\n", wuji_last_error());
return 1;
} Connect by Address
Manually connect using IP address and port:
Python
C
glove = manager.connect(address="192.168.1.100:50000", device_name="glove")WujiConnectTarget target = {
.kind = WUJI_CONNECT_TARGET_KIND_ADDR,
.value = "192.168.1.100:50000",
};
WujiDevice *glove = NULL;
wuji_connect(&target, "glove", NULL, &glove); Include the port in the address. Use IP:port for IPv4. IPv6 addresses aren’t supported. A bare IP address returns a missing-port error instead of being treated as a USB path. Serial port paths aren’t supported either — scan first, then connect by SN.
Connect by USB
Wuji Hand attaches over USB. Filter the scan results by transport type, then connect by serial number:
Python
C
from wuji_sdk import SdkManager, TransportType
manager = SdkManager.instance()
usb_devices = [d for d in manager.scan() if d.transport_type == TransportType.Usb]
hand = manager.connect(sn=usb_devices[0].sn, device_name="wuji_hand")
print(f"Connected: {hand.serial_number} ({hand.handedness_name()})")WujiDiscovered *devs = NULL;
size_t count = 0;
wuji_scan(&devs, &count);
WujiDevice *hand = NULL;
for (size_t i = 0; i < count; i++) {
if (devs[i].transport == WUJI_TRANSPORT_TYPE_USB) {
if (wuji_hand_connect_sn(devs[i].serial_number, "wuji_hand", &hand) != WUJI_STATUS_OK) {
fprintf(stderr, "connect failed: %s\n", wuji_last_error());
hand = NULL;
}
break;
}
}
wuji_discovered_free(devs, count); wuji_hand_connect_sn() is shorthand for wuji_connect() with SN targeting. Both return the same kind of device handle.
If a matching-handedness tactile glove is plugged in alongside the hand, the SDK auto-pairs it on connect. Check with hand.is_tactile_attached() in Python or wuji_hand_is_tactile_attached() in C. The value reflects the current attachment and turns false after the glove is unplugged at runtime. Once unplugged, the tactile status stream’s state becomes 0 (not present), other tactile reads and subscriptions fail with a tactile_not_present error, and the hand itself keeps working. Re-attaching the glove requires reconnecting the hand.
On a Mac with Apple silicon, Wuji Hand and its tactile glove need no extra USB driver. Unplugging the Wuji Hand USB cable reports USB I/O error: device disconnected. After plugging it back in, reconnect the device and recreate subscriptions.
Connect by Handedness
Connect to a two-handed device (such as Wuji Hand 2 or Wuji Glove) by left or right hand, without looking up a serial number first. The SDK scans the local network and selects the unique device by the fourth character of its serial number (J for left, K for right):
from wuji_sdk import Handedness
# Connect the right-hand device
hand = manager.connect(handedness=Handedness.Right, device_name="wuji_hand_2")
# Connect the left-hand glove
glove = manager.connect(handedness=Handedness.Left, device_name="wuji_glove") handedness is mutually exclusive with sn and address—specify only one.
C has no equivalent. In the wuji_scan() results, match serial_number[3] against 'J' or 'K' to isolate the target, then follow Connect by SN.
In Python, if no device matches the handedness, DeviceNotFound is raised. If multiple devices share the handedness, AmbiguousHandedness is raised with all candidate serial numbers. Specify sn explicitly instead.
Connection Options
Configure timeout, retries, and device sharing:
Python
C
from wuji_sdk import ConnectOptions
options = ConnectOptions(
timeout_ms=1000, # Connection timeout (milliseconds)
retry_count=3 # Number of retries
)
glove = manager.connect(
sn="WG1JA00XXXXXXXXX",
device_name="glove",
options=options
)WujiConnectOptions options = wuji_connect_options_default();
options.timeout_ms = 1000; // Connection timeout (milliseconds)
options.retry_count = 3; // Number of retries
WujiConnectTarget target = {
.kind = WUJI_CONNECT_TARGET_KIND_SN,
.value = "WG1JA00XXXXXXXXX",
};
WujiDevice *glove = NULL;
wuji_connect(&target, "glove", &options, &glove); enable_bridge (on by default) controls whether multiple SDK instances (including processes on other hosts) can connect to the same device. When enabled, this process shares the connected device. Turn it off for exclusive access — other instances can’t reach the device through this process.
In C, always start from wuji_connect_options_default() and override only the fields you need. Zero-initializing the whole struct also clears enable_bridge and background time sync, which changes connection behavior. Pass NULL to wuji_connect() when the defaults are fine.
Multi-device Management
The SDK supports connecting multiple devices simultaneously, each identified by a unique device_name:
Python
C
left = manager.connect(handedness=Handedness.Left, device_name="left_hand")
right = manager.connect(handedness=Handedness.Right, device_name="right_hand")
# Get all connected devices
all_devices = manager.get_connected_devices()
for name, device in all_devices:
print(f"{name}: {device.serial_number}")
# Get a device by name
left = manager.get_device(device_name="left_hand")WujiConnectTarget left_target = {
.kind = WUJI_CONNECT_TARGET_KIND_SN,
.value = "WG1JA00XXXXXXXXX",
};
WujiConnectTarget right_target = {
.kind = WUJI_CONNECT_TARGET_KIND_SN,
.value = "WG1KA00XXXXXXXXX",
};
WujiDevice *left = NULL, *right = NULL;
wuji_connect(&left_target, "left_hand", NULL, &left);
wuji_connect(&right_target, "right_hand", NULL, &right);
// C has no alias registry — keep the handles yourself
char name[64];
wuji_dev_device_name(left, name, sizeof(name));
printf("%s: connected=%u\n", name, wuji_dev_is_connected(left)); Use different device_name values to keep the left and right hand in the same process. Reconnecting to an already-active device raises SessionAlreadyExists in Python and returns a failure status in C. Neither drops the existing connection — keep using the existing handle.
Disconnecting
Python
C
# Disconnect a specific device
manager.disconnect(device_name="glove")
# Or disconnect via the device object
glove.disconnect()
# Disconnect all devices managed by this manager
manager.disconnect_all()// Disconnect first, then release the handle — both calls are required
wuji_dev_disconnect(glove);
wuji_dev_release(glove); When a device is disconnected, all subscriptions on that device are automatically closed. You’ll need to re-establish subscriptions after reconnecting.
The SDK owns the connection, and dropping a device object or handle variable doesn’t close it. In Python, deleting or replacing a device object leaves the connection active until you call disconnect() or disconnect_all(), or until the process exits, so long-running programs should disconnect explicitly in a finally block. In C, wuji_dev_release() only returns the handle, so call wuji_dev_disconnect() before releasing it. With an exclusive connection, leaving the connection open also prevents other clients from connecting to the device.
Interface List
| Operation | Python | C |
|---|---|---|
| Initialize and shut down the SDK | SdkManager.instance() | wuji_init(), wuji_shutdown() |
| Scan for devices | manager.scan() | wuji_scan(), wuji_discovered_free() |
| Connect the only discovered device | manager.auto_connect(device_name=...) | No equivalent — scan first, then call wuji_connect() with the serial number |
| Connect by serial number | manager.connect(sn=...) | wuji_connect() with target.kind set to WUJI_CONNECT_TARGET_KIND_SN |
| Connect by address | manager.connect(address=...) | wuji_connect() with target.kind set to WUJI_CONNECT_TARGET_KIND_ADDR |
| Connect a Wuji Hand over USB | Filter by TransportType.Usb, then manager.connect(sn=...) | wuji_hand_connect_sn() |
| Connect by handedness | manager.connect(handedness=...) | No equivalent — filter scan results on the fourth serial-number character, then call wuji_connect() |
| Configure connection parameters | ConnectOptions(...) | wuji_connect_options_default(), then override WujiConnectOptions fields |
| Read serial number and alias | device.serial_number, device.device_name | wuji_dev_serial_number(), wuji_dev_device_name() |
| Check connection state | device.is_connected | wuji_dev_is_connected() |
| Look up a device by alias | manager.get_device(device_name=...), manager.get_connected_devices() | No equivalent — keep the device handles yourself |
| Disconnect one device | device.disconnect(), manager.disconnect(device_name=...) | wuji_dev_disconnect(), wuji_dev_release() |
| Disconnect every device | manager.disconnect_all() | No equivalent — call wuji_dev_disconnect() on each handle |
Python reports failures as exceptions. C reports them as WujiStatus return codes, with the reason available from wuji_last_error(). For build flags, linking, memory ownership, and the full status code list, see the C Interface Reference.
ドキュメント