Skip to content

Commit 3340333

Browse files
committed
add device_hub to python api
1 parent feb8fa3 commit 3340333

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# License: Apache 2.0. See LICENSE file in root directory.
2+
# Copyright(c) 2025 RealSense Inc. All Rights Reserved.
3+
4+
import time
5+
import pyrealsense2 as rs
6+
from rspy import log, test
7+
8+
MAX_TRIES = 3
9+
DISCONNECT_TIMEOUT_SEC = 2
10+
11+
12+
dev, ctx = test.find_first_device_or_exit()
13+
hub = rs.device_hub(ctx)
14+
15+
# -------- Basic functionality --------
16+
test.start("device_hub: wait_for_device & is_connected")
17+
try:
18+
dev_from_hub = hub.wait_for_device()
19+
test.check(dev_from_hub is not None, "wait_for_device() did not return a device")
20+
test.check(hub.is_connected(dev_from_hub), "Device should be reported as connected")
21+
except:
22+
test.unexpected_exception()
23+
test.finish()
24+
25+
# -------- Disconnect detection via hardware reset --------
26+
test.start("device_hub: detect disconnect after hardware_reset")
27+
caught_once = False
28+
29+
for attempt in range(1, MAX_TRIES + 1):
30+
try:
31+
log.i(f"Attempt {attempt}/{MAX_TRIES}: issuing hardware_reset()")
32+
dev.hardware_reset()
33+
34+
# Wait until hub reports this handle as disconnected
35+
t = time.time()
36+
while time.time() - t < DISCONNECT_TIMEOUT_SEC:
37+
if not hub.is_connected(dev):
38+
caught_once = True
39+
break
40+
41+
if caught_once:
42+
break
43+
44+
except:
45+
test.unexpected_exception()
46+
47+
test.check(caught_once, f"Failed to observe a disconnect in {MAX_TRIES} hardware reset attempt(s)")
48+
test.finish()
49+
50+
test.print_results_and_exit()

wrappers/python/pyrs_context.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,18 @@ void init_context(py::module &m) {
4040
.def("unload_tracking_module", &rs2::context::unload_tracking_module); // No docstring in C++
4141

4242
// rs2::device_hub
43+
py::class_<rs2::device_hub>(m, "device_hub",
44+
"Encapsulates connect/disconnect handling and waiting for devices.")
45+
.def(py::init<rs2::context>(),
46+
py::arg("ctx"),
47+
py::keep_alive<1, 2>(), // keep ctx alive as long as hub lives
48+
"Create a device_hub bound to the given context.")
49+
.def("wait_for_device",
50+
&rs2::device_hub::wait_for_device,
51+
"If a device is connected return it, otherwise wait until one connects.")
52+
.def("is_connected",
53+
&rs2::device_hub::is_connected,
54+
py::arg("device"),
55+
"Return True if the given device is still connected.");
4356
/** end rs_context.hpp **/
4457
}

0 commit comments

Comments
 (0)