pyorbbec 1.0.1.7__py3-none-any.whl → 1.0.1.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {pyorbbec-1.0.1.7.dist-info → pyorbbec-1.0.1.8.dist-info}/METADATA +1 -1
  2. pyorbbec-1.0.1.8.dist-info/RECORD +59 -0
  3. pyorbbecsdk/examples/.gitkeep +0 -0
  4. pyorbbecsdk/examples/OrbbecSDK.dll +0 -0
  5. pyorbbecsdk/examples/OrbbecSDK.lib +0 -0
  6. pyorbbecsdk/examples/README.md +26 -0
  7. pyorbbecsdk/examples/__pycache__/utils.cpython-313.pyc +0 -0
  8. pyorbbecsdk/examples/callback.py +303 -0
  9. pyorbbecsdk/examples/color.py +64 -0
  10. pyorbbecsdk/examples/coordinate_transform.py +184 -0
  11. pyorbbecsdk/examples/depth.py +107 -0
  12. pyorbbecsdk/examples/depth_work_mode.py +50 -0
  13. pyorbbecsdk/examples/device_firmware_update.py +155 -0
  14. pyorbbecsdk/examples/device_optional_depth_presets_update.py +142 -0
  15. pyorbbecsdk/examples/enumerate.py +118 -0
  16. pyorbbecsdk/examples/extensions/depthengine/depthengine.dll +0 -0
  17. pyorbbecsdk/examples/extensions/depthengine/depthengine.lib +0 -0
  18. pyorbbecsdk/examples/extensions/filters/FilterProcessor.dll +0 -0
  19. pyorbbecsdk/examples/extensions/filters/ob_priv_filter.dll +0 -0
  20. pyorbbecsdk/examples/extensions/firmwareupdater/firmwareupdater.dll +0 -0
  21. pyorbbecsdk/examples/extensions/frameprocessor/ob_frame_processor.dll +0 -0
  22. pyorbbecsdk/examples/hdr.py +216 -0
  23. pyorbbecsdk/examples/hot_plug.py +160 -0
  24. pyorbbecsdk/examples/hw_d2c_align.py +135 -0
  25. pyorbbecsdk/examples/imu.py +60 -0
  26. pyorbbecsdk/examples/infrared.py +115 -0
  27. pyorbbecsdk/examples/logger.py +55 -0
  28. pyorbbecsdk/examples/metadata.py +64 -0
  29. pyorbbecsdk/examples/multi_device.py +169 -0
  30. pyorbbecsdk/examples/multi_streams.py +219 -0
  31. pyorbbecsdk/examples/net_device.py +158 -0
  32. pyorbbecsdk/examples/playback.py +277 -0
  33. pyorbbecsdk/examples/point_cloud.py +90 -0
  34. pyorbbecsdk/examples/post_processing.py +119 -0
  35. pyorbbecsdk/examples/preset.py +67 -0
  36. pyorbbecsdk/examples/pyorbbecsdk.cp313-win_amd64.pyd +0 -0
  37. pyorbbecsdk/examples/quick_start.py +90 -0
  38. pyorbbecsdk/examples/recorder.py +236 -0
  39. pyorbbecsdk/examples/requirements.txt +9 -0
  40. pyorbbecsdk/examples/save_image_to_disk.py +106 -0
  41. pyorbbecsdk/examples/sync_align.py +109 -0
  42. pyorbbecsdk/examples/two_devices_sync.py +233 -0
  43. pyorbbecsdk/examples/utils.py +127 -0
  44. pyorbbec-1.0.1.7.dist-info/RECORD +0 -18
  45. {pyorbbec-1.0.1.7.dist-info → pyorbbec-1.0.1.8.dist-info}/WHEEL +0 -0
  46. {pyorbbec-1.0.1.7.dist-info → pyorbbec-1.0.1.8.dist-info}/licenses/LICENSE +0 -0
  47. {pyorbbec-1.0.1.7.dist-info → pyorbbec-1.0.1.8.dist-info}/licenses/NOTICE +0 -0
  48. {pyorbbec-1.0.1.7.dist-info → pyorbbec-1.0.1.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,107 @@
1
+ # ******************************************************************************
2
+ # Copyright (c) 2024 Orbbec 3D Technology, Inc
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:# www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ******************************************************************************
16
+ import time
17
+
18
+ import cv2
19
+ import numpy as np
20
+
21
+ from pyorbbecsdk import *
22
+
23
+ ESC_KEY = 27
24
+ PRINT_INTERVAL = 1 # seconds
25
+ MIN_DEPTH = 20 # 20mm
26
+ MAX_DEPTH = 10000 # 10000mm
27
+
28
+
29
+ class TemporalFilter:
30
+ def __init__(self, alpha):
31
+ self.alpha = alpha
32
+ self.previous_frame = None
33
+
34
+ def process(self, frame):
35
+ if self.previous_frame is None:
36
+ result = frame
37
+ else:
38
+ result = cv2.addWeighted(frame, self.alpha, self.previous_frame, 1 - self.alpha, 0)
39
+ self.previous_frame = result
40
+ return result
41
+
42
+
43
+ def main():
44
+ config = Config()
45
+ pipeline = Pipeline()
46
+ temporal_filter = TemporalFilter(alpha=0.5)
47
+ try:
48
+ profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
49
+ assert profile_list is not None
50
+ depth_profile = profile_list.get_default_video_stream_profile()
51
+ assert depth_profile is not None
52
+ print("depth profile: ", depth_profile)
53
+ config.enable_stream(depth_profile)
54
+ except Exception as e:
55
+ print(e)
56
+ return
57
+ pipeline.start(config)
58
+ last_print_time = time.time()
59
+ while True:
60
+ try:
61
+ frames = pipeline.wait_for_frames(100)
62
+ if frames is None:
63
+ continue
64
+ depth_frame = frames.get_depth_frame()
65
+ if depth_frame is None:
66
+ continue
67
+ depth_format = depth_frame.get_format()
68
+ if depth_format != OBFormat.Y16:
69
+ print("depth format is not Y16")
70
+ continue
71
+ width = depth_frame.get_width()
72
+ height = depth_frame.get_height()
73
+ scale = depth_frame.get_depth_scale()
74
+
75
+ depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
76
+ depth_data = depth_data.reshape((height, width))
77
+
78
+ depth_data = depth_data.astype(np.float32) * scale
79
+ depth_data = np.where((depth_data > MIN_DEPTH) & (depth_data < MAX_DEPTH), depth_data, 0)
80
+ depth_data = depth_data.astype(np.uint16)
81
+ # Apply temporal filtering
82
+ depth_data = temporal_filter.process(depth_data)
83
+
84
+ center_y = int(height / 2)
85
+ center_x = int(width / 2)
86
+ center_distance = depth_data[center_y, center_x]
87
+
88
+ current_time = time.time()
89
+ if current_time - last_print_time >= PRINT_INTERVAL:
90
+ print("center distance: ", center_distance)
91
+ last_print_time = current_time
92
+
93
+ depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
94
+ depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)
95
+
96
+ cv2.imshow("Depth Viewer", depth_image)
97
+ key = cv2.waitKey(1)
98
+ if key == ord('q') or key == ESC_KEY:
99
+ break
100
+ except KeyboardInterrupt:
101
+ break
102
+ cv2.destroyAllWindows()
103
+ pipeline.stop()
104
+
105
+
106
+ if __name__ == "__main__":
107
+ main()
@@ -0,0 +1,50 @@
1
+ # ******************************************************************************
2
+ # Copyright (c) 2024 Orbbec 3D Technology, Inc
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:# www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ******************************************************************************
16
+ from pyorbbecsdk import *
17
+
18
+ ESC = 27
19
+
20
+
21
+ def main():
22
+ pipeline = Pipeline()
23
+ assert pipeline is not None
24
+ device = pipeline.get_device()
25
+ assert device is not None
26
+ if not device.is_property_supported(OBPropertyID.OB_STRUCT_CURRENT_DEPTH_ALG_MODE,
27
+ OBPermissionType.PERMISSION_READ_WRITE):
28
+ print("Current device not support depth work mode!")
29
+ return
30
+ current_depth_work_mode = device.get_depth_work_mode()
31
+ assert current_depth_work_mode is not None
32
+ print("Current depth work mode: ", current_depth_work_mode)
33
+ depth_work_mode_list = device.get_depth_work_mode_list()
34
+ assert depth_work_mode_list is not None
35
+ for i in range(depth_work_mode_list.get_count()):
36
+ depth_work_mode = depth_work_mode_list.get_depth_work_mode_by_index(i)
37
+ assert depth_work_mode is not None
38
+ print("{}. {}".format(i, depth_work_mode))
39
+ if depth_work_mode_list.get_count() > 1:
40
+ index = int(input("Please input depth work mode index: "))
41
+ if depth_work_mode_list.get_count() > index >= 0:
42
+ select_depth_work_mode = depth_work_mode_list.get_depth_work_mode_by_index(index)
43
+ assert select_depth_work_mode is not None
44
+ device.set_depth_work_mode(select_depth_work_mode.name)
45
+ assert select_depth_work_mode == device.get_depth_work_mode()
46
+ print("Set depth work mode to {} success!".format(select_depth_work_mode))
47
+
48
+
49
+ if __name__ == '__main__':
50
+ main()
@@ -0,0 +1,155 @@
1
+ # ******************************************************************************
2
+ # Copyright (c) 2024 Orbbec 3D Technology, Inc
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:# www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ******************************************************************************
16
+
17
+ import os
18
+ import sys
19
+ from pyorbbecsdk import *
20
+
21
+ devices = []
22
+ first_call = True
23
+
24
+
25
+ def get_firmware_path():
26
+ """Prompt user for the firmware file path with improved Windows compatibility."""
27
+ while True:
28
+ firmware_path = input("Please input the path of the firmware file (.bin) to be updated (or 'q' to quit): ")
29
+
30
+ if firmware_path.lower() == 'q':
31
+ sys.exit("Exiting...")
32
+
33
+ # Clean up the input path
34
+ firmware_path = firmware_path.strip().strip("'").strip('"') # Remove quotes and extra spaces
35
+
36
+ # Normalize path separators for Windows compatibility
37
+ firmware_path = os.path.normpath(firmware_path)
38
+
39
+ try:
40
+ # Convert to absolute path with proper handling of relative paths
41
+ firmware_path = os.path.abspath(os.path.expanduser(firmware_path))
42
+
43
+ # Verify the file exists and has .bin extension
44
+ if os.path.isfile(firmware_path) and firmware_path.lower().endswith(".bin"):
45
+ # Try to open the file to verify access permissions
46
+ try:
47
+ with open(firmware_path, 'rb') as f:
48
+ pass
49
+ print(f"Firmware file confirmed: {firmware_path}\n")
50
+ return firmware_path
51
+ except PermissionError:
52
+ print("Error: Permission denied. Cannot access the specified file.\n")
53
+ except Exception as e:
54
+ print(f"Error accessing file: {str(e)}\n")
55
+ else:
56
+ print("Invalid file format or path. Please provide a valid .bin file.\n")
57
+ except Exception as e:
58
+ print(f"Error processing path: {str(e)}\n")
59
+ print("Please provide a valid file path.\n")
60
+
61
+
62
+ def print_device_list():
63
+ """Print the list of connected devices."""
64
+ print("--------------------------------------------------------------------------------")
65
+ for i, device in enumerate(devices):
66
+ device_info = device.get_device_info()
67
+ print(
68
+ f"[{i}] Device: {device_info.get_name()} | SN: {device_info.get_serial_number()} | Firmware version: {device_info.get_firmware_version()}")
69
+ print("--------------------------------------------------------------------------------")
70
+
71
+
72
+ def select_device():
73
+ """Allow user to select a device by index."""
74
+ while True:
75
+ choice = input(
76
+ "Please select a device to update the firmware, enter 'l' to list devices, or 'q' to quit: \n").strip()
77
+
78
+ if choice.lower() == 'q':
79
+ return None
80
+
81
+ if choice.lower() == 'l':
82
+ print_device_list()
83
+ continue
84
+
85
+ try:
86
+ index = int(choice)
87
+ if 0 <= index < len(devices):
88
+ print()
89
+ return index
90
+ else:
91
+ print("Invalid index. Please select a valid device index.")
92
+ except ValueError:
93
+ print("Invalid input. Please enter a numeric index.")
94
+
95
+
96
+ def firmware_update_callback(state, message, percent):
97
+ """Callback function to report firmware update progress."""
98
+ global first_call
99
+ if first_call:
100
+ first_call = False
101
+ else:
102
+ print("\033[F\033[F", end="") # Move up two lines to overwrite previous output
103
+
104
+ print(f"Progress: {percent}%")
105
+ print(f"Status : {state}")
106
+ print(f"Message : {message}\n")
107
+
108
+
109
+ def main():
110
+ global first_call
111
+ try:
112
+ context = Context()
113
+ device_list = context.query_devices()
114
+
115
+ if device_list.get_count() == 0:
116
+ print("No device found. Please connect a device first!")
117
+ input("Press Enter to exit...")
118
+ return
119
+
120
+ for i in range(device_list.get_count()):
121
+ devices.append(device_list[i])
122
+
123
+ print("Devices found:")
124
+ print_device_list()
125
+
126
+ while True:
127
+ first_call = True
128
+ device_index = select_device()
129
+
130
+ if device_index is None:
131
+ break
132
+
133
+ firmware_path = get_firmware_path()
134
+
135
+ print("Upgrading device firmware, please wait...\n")
136
+ try:
137
+ devices[device_index].update_firmware(firmware_path, firmware_update_callback, async_update=False)
138
+ print("Firmware update completed successfully! Please reboot the device.")
139
+ except Exception as e:
140
+ print("\nThe upgrade was interrupted! An error occurred!")
141
+ print(f"Error message: {str(e)}")
142
+ input("Press Enter to exit...")
143
+ break
144
+
145
+ if input("Enter 'q' to quit, or any other key to continue: ").lower() == 'q':
146
+ break
147
+
148
+ except Exception as e:
149
+ print(f"Error: {str(e)}")
150
+ input("Press Enter to exit.")
151
+ sys.exit(1)
152
+
153
+
154
+ if __name__ == "__main__":
155
+ main()
@@ -0,0 +1,142 @@
1
+ import time
2
+ import sys
3
+ from pyorbbecsdk import *
4
+
5
+ # Callback function to display update progress
6
+ def preset_update_callback(first_call, state, message, percent):
7
+ if not first_call:
8
+ sys.stdout.write("\033[3F") # Move cursor up 3 lines
9
+ sys.stdout.write("\033[K") # Clear the current line
10
+ print(f"Progress: {percent}%")
11
+ sys.stdout.write("\033[K")
12
+ print(f"Status : {state}")
13
+ sys.stdout.write("\033[K")
14
+ print(f"Message : {message}\n", end='')
15
+
16
+ # Helper function to return the update state message
17
+ # def get_update_status(state):
18
+ # if state == OBFwUpdateState.STAT_VERIFY_SUCCESS:
19
+ # return "Image file verification success"
20
+ # elif state == OBFwUpdateState.STAT_FILE_TRANSFER:
21
+ # return "File transfer in progress"
22
+ # elif state == OBFwUpdateState.STAT_DONE:
23
+ # return "Update completed"
24
+ # elif state == OBFwUpdateState.STAT_DONE_WITH_DUPLICATES:
25
+ # return "Update completed, duplicated presets have been ignored"
26
+ # elif state == OBFwUpdateState.STAT_IN_PROGRESS:
27
+ # return "Update in progress"
28
+ # elif state == OBFwUpdateState.STAT_START:
29
+ # return "Starting the update"
30
+ # elif state == OBFwUpdateState.STAT_VERIFY_IMAGE:
31
+ # return "Verifying image file"
32
+ # else:
33
+ # return "Unknown status or error"
34
+
35
+ # Function to simulate input of preset file paths
36
+ def get_preset_paths():
37
+ paths = []
38
+ print("Please input the file paths of the optional depth preset file (.bin):")
39
+ print(" - Press 'Enter' to finish this input")
40
+ print(" - Press 'Q' or 'q' to exit the program")
41
+ while len(paths) < 10:
42
+ path = input("Enter Path: ")
43
+ if path.lower() == 'q':
44
+ return None
45
+ if path == '':
46
+ if len(paths) == 0:
47
+ print("You didn't input any file paths")
48
+ continue
49
+ break
50
+ if path.endswith(".bin"):
51
+ paths.append(path)
52
+ else:
53
+ print("Invalid file format. Please provide a .bin file.")
54
+ return paths
55
+
56
+ # Main loop to simulate device selection, preset update, and handling
57
+ def main():
58
+ # Assuming `devices` is a list of `Device` objects that you've already gathered
59
+ devices = []
60
+ context = Context()
61
+ device_list = context.query_devices()
62
+
63
+ if device_list.get_count() == 0:
64
+ print("No device found. Please connect a device first!")
65
+ input("Press Enter to exit...")
66
+ return
67
+
68
+ for i in range(device_list.get_count()):
69
+ devices.append(device_list[i])
70
+
71
+ print("Devices found:")
72
+ print_device_list(devices)
73
+
74
+ while True:
75
+ device = select_device(devices) # User selects a device
76
+
77
+ if not device:
78
+ break
79
+
80
+ preset_paths = get_preset_paths()
81
+ if not preset_paths:
82
+ break
83
+
84
+ print("Start to update optional depth preset, please wait a moment...\n")
85
+
86
+ # Pass the paths list to the update function and update via callback
87
+ try:
88
+ device.update_optional_depth_presets(
89
+ preset_paths,
90
+ lambda state, message, percent: preset_update_callback(True, state, message, percent)
91
+ )
92
+ except Exception as e:
93
+ print(f"\nThe update was interrupted! An error occurred: {str(e)}")
94
+ break
95
+
96
+ print("\nUpdate completed successfully!")
97
+ # Assuming `print_preset(device)` will show the updated preset information
98
+ print_preset(device)
99
+
100
+ if not should_continue():
101
+ break
102
+
103
+ # Function to print device list (similar to the C++ printDeviceList function)
104
+ def print_device_list(devices):
105
+ for i, device in enumerate(devices):
106
+ print(f"[{i}] Device: {device.get_device_info().get_name()} | "
107
+ f"SN: {device.get_device_info().get_serial_number()} | "
108
+ f"Firmware version: {device.get_device_info().get_firmware_version()}")
109
+
110
+ # Function to let the user select a device
111
+ def select_device(devices):
112
+ while True:
113
+ device_index = input("Please select a device by index, or press 'q' to quit: ")
114
+ if device_index.lower() == 'q':
115
+ return None
116
+ try:
117
+ index = int(device_index)
118
+ if 0 <= index < len(devices):
119
+ return devices[index]
120
+ else:
121
+ print("Invalid index. Please try again.")
122
+ except ValueError:
123
+ print("Invalid input. Please enter a number.")
124
+
125
+ # Function to check if the user wants to continue
126
+ def should_continue():
127
+ input_str = input("Enter 'Q' or 'q' to quit, or any other key to continue: ")
128
+ return input_str.lower() != 'q'
129
+
130
+ # Placeholder function to retrieve devices, implement this to match your system setup
131
+ def get_devices():
132
+ # Example: Returning a list of Device objects.
133
+ # In real usage, you'll need to query connected devices.
134
+ return []
135
+
136
+ # Placeholder function to print preset info after the update, implement as needed
137
+ def print_preset(device):
138
+ print(f"Updated preset for device {device.get_device_info().get_name()}")
139
+
140
+ # Run the program
141
+ if __name__ == "__main__":
142
+ main()
@@ -0,0 +1,118 @@
1
+ # ******************************************************************************
2
+ # Copyright (c) 2024 Orbbec 3D Technology, Inc
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http:# www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ******************************************************************************
16
+
17
+ import sys
18
+ from pyorbbecsdk import *
19
+
20
+ ESC_KEY = 'q'
21
+
22
+
23
+ def get_input_option():
24
+ """Get user input option, return -1 to exit"""
25
+ option = input("Please enter an option (or press 'q' to exit): ")
26
+ if option.lower() == ESC_KEY:
27
+ return -1
28
+ try:
29
+ return int(option)
30
+ except ValueError:
31
+ print("Invalid input, please enter a number!")
32
+ return get_input_option()
33
+
34
+
35
+ def print_video_profile(profile, index, sensor_type):
36
+ """Print video stream profile information, including sensor type"""
37
+ # Check if VideoStreamProfile has the required methods
38
+ if all(hasattr(profile, attr) for attr in ["get_format", "get_width", "get_height", "get_fps"]):
39
+ format_name = profile.get_format()
40
+ width = profile.get_width()
41
+ height = profile.get_height()
42
+ fps = profile.get_fps()
43
+ print(
44
+ f"Sensor type: {sensor_type} | {index}. format: {format_name}, width: {width}, height: {height}, fps: {fps}")
45
+ else:
46
+ print(f"{index}. VideoStreamProfile is missing expected methods")
47
+
48
+
49
+ def enumerate_stream_profiles(sensor):
50
+ """List stream profiles based on sensor type"""
51
+ try:
52
+ stream_profile_list = sensor.get_stream_profile_list()
53
+ except Exception as e:
54
+ print(f"Unable to get StreamProfileList: {e}")
55
+ return
56
+
57
+ sensor_type = sensor.get_type()
58
+ print("Available stream profiles:")
59
+ for index in range(stream_profile_list.get_count()):
60
+ try:
61
+ profile = stream_profile_list.get_stream_profile_by_index(index)
62
+ profile_type = type(profile).__name__
63
+ print(f"Profile #{index} type: {profile_type}")
64
+ if profile_type == "VideoStreamProfile":
65
+ print_video_profile(profile, index, sensor_type)
66
+ else:
67
+ print(f"{index}. Unknown video stream profile type")
68
+ except Exception as e:
69
+ print(f"Unable to retrieve stream profile: {e}")
70
+
71
+
72
+ def enumerate_sensors(device):
73
+ """List device sensor information and allow user to select a sensor"""
74
+ sensor_list = device.get_sensor_list()
75
+ print("Available sensor list:")
76
+ for index in range(sensor_list.get_count()):
77
+ sensor_type = sensor_list.get_type_by_index(index)
78
+ print(f" - {index}. Sensor type: {sensor_type}")
79
+
80
+ # Prompt user to select a sensor
81
+ sensor_selected = get_input_option()
82
+ if sensor_selected == -1:
83
+ return
84
+ if sensor_selected >= sensor_list.get_count() or sensor_selected < 0:
85
+ print("Invalid input, please select again!")
86
+ return enumerate_sensors(device)
87
+
88
+ sensor = sensor_list.get_sensor_by_index(sensor_selected)
89
+ print(f"Selected sensor type: {sensor.get_type()}")
90
+ enumerate_stream_profiles(sensor)
91
+
92
+
93
+ def main():
94
+ context = Context()
95
+ device_list = context.query_devices()
96
+ if device_list.get_count() < 1:
97
+ print("No device found, please connect a device and try again.")
98
+ return
99
+
100
+ print("Enumerated devices:")
101
+ for index in range(device_list.get_count()):
102
+ device = device_list[index]
103
+ device_info = device.get_device_info()
104
+ print(
105
+ f" - {index}. Device name: {device_info.get_name()}, PID: {device_info.get_pid()}, Serial Number: {device_info.get_serial_number()}")
106
+
107
+ # Default to selecting the first device
108
+ print(f"Please select a device, show between 0 and {device_list.get_count() - 1}")
109
+ device_selected = get_input_option()
110
+ if device_selected == -1:
111
+ print("Exiting...")
112
+ return
113
+ selected_device = device_list[device_selected]
114
+ enumerate_sensors(selected_device)
115
+
116
+
117
+ if __name__ == "__main__":
118
+ main()