async def do_show_new_image_template_dialog(new_name: str, variable_type: str, variable_tags: str, core: "PyriWebUIBrowser"): try: db = core.device_manager.get_device_subscription( "variable_storage").GetDefaultClient() img_var_names = await db.async_filter_variables( "globals", "", ["image"], None) if len(img_var_names) <= 0: js.alert("No source images available!") return dialog_html = importlib_resources.read_text( __package__, "new_image_template_dialog.html") dialog_obj = NewImageTemplateDialog(new_name, core, core.device_manager) el = js.document.createElement('div') el.id = "new_image_template_dialog_wrapper" js.document.getElementById("wrapper").appendChild(el) dialog = js.Vue.new( js.python_to_js({ "el": "#new_image_template_dialog_wrapper", "template": dialog_html, "data": { "image_selected": "", "image_select_options": [], }, "methods": { "handle_create": dialog_obj.handle_create, "handle_hidden": dialog_obj.handle_hidden, "image_select_changed": dialog_obj.image_select_changed, "image_reset": dialog_obj.image_reset, "image_rot_m5": dialog_obj.image_rot_m5, "image_rot_p5": dialog_obj.image_rot_p5 } })) dialog_obj.init_vue(dialog) img_vars = [] for v in img_var_names: img_vars.append({"value": v, "text": v}) dialog["$data"].image_select_options = js.python_to_js(img_vars) if len(img_vars) > 0: dialog["$data"].image_selected = img_vars[0]["value"] core.create_task(dialog_obj.set_image(img_var_names[0])) except: js.alert( f"Image template creating failed:\n\n{traceback.format_exc()}") dialog["$bvModal"].show("new_image_template")
def refresh_cameras_table(self,*args): try: cameras = util.get_devices_with_type(self.core,"com.robotraconteur.imaging.Camera") self.vue["$data"].cameras = js.python_to_js([{"local_device_name": d} for d in cameras]) except: traceback.print_exc()
async def set_image(self, image_global_name): try: db = self.device_manager.get_device_subscription( "variable_storage").GetDefaultClient() img1 = await db.async_getf_variable_value("globals", image_global_name, None) img = img1.data d_encoded = str(base64.b64encode(img.data))[2:-1] if np.array_equal(img.data[0:3], np.array([0xFF, 0xD8, 0xFF], dtype=np.uint8)): img_src = "data:image/jpeg;base64," + d_encoded elif np.array_equal(img.data[0:3], np.array([0x89, 0x50, 0x4E], dtype=np.uint8)): img_src = "data:image/png;base64," + d_encoded else: js.alert("Invalid image magic") raise Exception("Invalid image magic") if self.cropper is None: img_el = js.document.getElementById("training_image") img_el.src = img_src self.cropper = js.Cropper.new(img_el, js.python_to_js({"viewMode": 2})) else: self.cropper.reset() self.cropper.replace(img_src) except: traceback.print_exc()
async def do_device_info(self, dev_name): try: dev_manager = self.device_manager.device_manager.GetDefaultClient() d = await dev_manager.async_getf_device_info(dev_name, None) vue_devs = [] ident_util = IdentifierUtil(client_obj=dev_manager) d2 = { "device": ident_util.IdentifierToString(d.device), "parent_device": ident_util.IdentifierToString(d.parent_device), "manufacturer": ident_util.IdentifierToString(d.manufacturer), "model": ident_util.IdentifierToString(d.model), "serial_number": d.serial_number, "user_description": d.user_description, "service_name": d.service_name, "urls": "<br>".join(d.urls), "root_object_type": d.root_object_type, "root_object_implements": "<br>".join(d.root_object_implements) } vue_devs.append(d2) self.vue["$data"]["selected_device_info"] = js.python_to_js( vue_devs) self.vue["$bvModal"].show("device-info-modal") except: traceback.print_exc() js.alert(f"Get device info failed:\n\n{traceback.format_exc()}")
async def do_refresh_device_add(self): try: dev_manager = self.device_manager.device_manager.GetDefaultClient() detected_devices = await dev_manager.async_getf_detected_devices( None) vue_devs = [] ident_util = IdentifierUtil(client_obj=dev_manager) for d in detected_devices: d2 = { "device": ident_util.IdentifierToString(d.device), "parent_device": ident_util.IdentifierToString(d.parent_device), "manufacturer": ident_util.IdentifierToString(d.manufacturer), "model": ident_util.IdentifierToString(d.model), "serial_number": d.serial_number, "user_description": d.user_description, "service_name": d.service_name, "urls": "<br>".join(d.urls), "root_object_type": d.root_object_type, "root_object_implements": "<br>".join(d.root_object_implements) } vue_devs.append(d2) self.vue["$data"]["detected_devices"] = js.python_to_js(vue_devs) except: traceback.print_exc() js.alert(f"Refresh add device failed:\n\n{traceback.format_exc()}")
def __init__(self, camera_local_name, core, device_manager): self.vue = None self.core = core self.device_manager = device_manager self.camera_local_name = camera_local_name camera_viewer_panel_config = { "type": "component", "componentName": f"camera_viewer", "componentState": { "camera_local_name": camera_local_name }, "title": camera_local_name, "id": f"camera_viewer_{camera_local_name}", "isClosable": True } core.layout.layout.root.getItemsById("vision")[0].addChild(js.python_to_js(camera_viewer_panel_config)) viewer_panel_el = core.layout.layout.root.getItemsById(f"camera_viewer_{camera_local_name}")[0].element self.viewer_img = viewer_panel_el.find("#camera_viewer_img")[0] viewer_panel_toolbar = viewer_panel_el.find("#camera_viewer_panel_toolbar")[0] print(f"viewer_img: {self.viewer_img}") self.viewer_connected = False self.vue = js.Vue.new(js.python_to_js({ "el": viewer_panel_toolbar, "data": { "capturing_sequence": False, "captured_sequence_global_name": "", "captured_sequence_count": 0, "save_system_state_checked": True }, "methods": { "save_to_globals": self.save_to_globals, "save_sequence_to_globals": self.save_sequence_to_globals, "sequence_capture_next": self.sequence_capture_next, "sequence_capture_done": self.sequence_capture_done, "sequence_capture_cancel": self.sequence_capture_cancel } })) self.core.create_task(self._run_viewer())
def init_golden_layout(self): layoutContainer = js.jQuery.find("#layoutContainer") self._layout = js.GoldenLayout.new( js.python_to_js(_golden_layout_config), layoutContainer) self._layout.init() js.jQuery(js.window).resize(lambda _: self._layout.updateSize())
def do_show_new_camera_calibration_extrinsic_dialog2(new_name: str, camera_pose, display_image, core: "PyriWebUIBrowser"): try: camera_calib = core.device_manager.get_device_subscription("vision_camera_calibration").GetDefaultClient() dialog2_html = importlib_resources.read_text(__package__,"new_calibrate_extrinsic_dialog2.html") el = js.document.createElement('div') el.id = "new_calibrate_extrinsic_dialog2_wrapper" js.document.getElementById("wrapper").appendChild(el) def handle_hidden(*args): try: el.parentElement.removeChild(el) except: traceback.print_exc() geom_util = GeometryUtil(client_obj=camera_calib) xyz, rpy1, _, _ = geom_util.named_pose_to_xyz_rpy(camera_pose.pose) rpy = np.rad2deg(rpy1) x = f"{xyz[0]:4e}" y = f"{xyz[1]:4e}" z = f"{xyz[2]:4e}" r_r = f"{rpy[0]:4e}" r_p = f"{rpy[1]:4e}" r_y = f"{rpy[2]:4e}" i=0 d_encoded = str(base64.b64encode(display_image.data))[2:-1] disp_img_src = "data:image/jpeg;base64," + d_encoded # TODO: check for png? dialog = js.Vue.new(js.python_to_js({ "el": "#new_calibrate_extrinsic_dialog2_wrapper", "template": dialog2_html, "data": { "x": x, "y": y, "z": z, "r_r": r_r, "r_p": r_p, "r_y": r_y, "disp_img": disp_img_src }, "methods": { "handle_hidden": handle_hidden } })) dialog["$bvModal"].show("new_vision_camera_calibrate_extrinsic2") except: traceback.print_exc()
def handle_create(self, *args): try: cropped_canvas = self.cropper.getCroppedCanvas( js.python_to_js({"imageSmoothingEnabled": False})) img_b64 = cropped_canvas.toDataURL('image/png') img_b64 = img_b64.replace("data:image/png;base64,", "") img_bytes = base64.b64decode(img_b64) img_np = np.frombuffer(img_bytes, np.uint8) self.core.create_task( self.do_handle_create(img_np, cropped_canvas.width, cropped_canvas.height)) except: js.alert( f"Save image template failed:\n\n{traceback.format_exc()}")
async def add_welcome_panel(panel_type: str, core: PyriWebUIBrowser, parent_element: Any): assert panel_type == "welcome" welcome_panel_html = importlib_resources.read_text(__package__, "welcome_panel.html") panel_config = { "type": "component", "componentName": "welcome", "componentState": {}, "title": "Welcome", "id": "welcome", "isClosable": False } gl = core.layout.layout def register_welcome(container, state): container.getElement().html(welcome_panel_html) core.layout.register_component("welcome", register_welcome) core.layout.add_panel(panel_config) core.layout.add_panel_menu_item("welcome", "Welcome") welcome_panel_obj = PyriWelcomePanel(core) welcome_counter = js.Vue.new( js.python_to_js({ "el": "#welcome_counter", "data": { "count": 10, "seqno": -1, "active_device_names": [] }, "methods": { "increment": welcome_panel_obj.increment, "decrement": welcome_panel_obj.decrement } })) welcome_panel_obj.init_vue(welcome_counter) core.create_task(welcome_panel_obj.run()) return welcome_panel_obj
async def do_show_new_camera_calibration_intrinsic_dialog( new_name: str, variable_type: str, variable_tags: str, core: "PyriWebUIBrowser"): try: core.device_manager.connect_device("vision_camera_calibration") dialog_html = importlib_resources.read_text( __package__, "new_calibrate_intrinsic_dialog.html") dialog_obj = NewCameraIntrinsicCalibrationDialog( new_name, core, core.device_manager) el = js.document.createElement('div') el.id = "new_calibrate_intrinsic_dialog_wrapper" js.document.getElementById("wrapper").appendChild(el) dialog = js.Vue.new( js.python_to_js({ "el": "#new_calibrate_intrinsic_dialog_wrapper", "template": dialog_html, "data": { "camera_selected": "", "camera_select_options": [], "image_sequence_selected": "", "image_sequence_select_options": [], "calibration_target_selected": "", "calibration_target_select_options": [] }, "methods": { "handle_create": dialog_obj.handle_create, "handle_hidden": dialog_obj.handle_hidden } })) dialog_obj.init_vue(dialog) cameras = [] camera_names = util.get_devices_with_type( core, "com.robotraconteur.imaging.Camera") cameras = util.device_names_to_dropdown_options(camera_names) dialog["$data"].camera_select_options = js.python_to_js(cameras) if len(cameras) > 0: dialog["$data"].camera_selected = cameras[0]["value"] db = core.device_manager.get_device_subscription( "variable_storage").GetDefaultClient() seq_var_names = await db.async_filter_variables( "globals", "", ["image_sequence"], None) seq_vars = [] for v in seq_var_names: seq_vars.append({"value": v, "text": v}) dialog["$data"].image_sequence_select_options = js.python_to_js( seq_vars) if len(seq_vars) > 0: dialog["$data"].image_sequence_selected = seq_vars[0]["value"] cal = [{"value": "chessboard", "text": "chessboard"}] dialog["$data"].calibration_target_select_options = js.python_to_js( cal) dialog["$data"].calibration_target_selected = "chessboard" dialog["$bvModal"].show("new_vision_camera_calibrate_intrinsic") except: js.alert(f"Calibration failed:\n\n{traceback.format_exc()}")
def do_show_new_camera_calibration_intrinsic_dialog2(new_name: str, calibration_res, display_images, core: "PyriWebUIBrowser"): try: dialog2_html = importlib_resources.read_text( __package__, "new_calibrate_intrinsic_dialog2.html") el = js.document.createElement('div') el.id = "new_calibrate_intrinsic_dialog2_wrapper" js.document.getElementById("wrapper").appendChild(el) def handle_hidden(*args): try: el.parentElement.removeChild(el) except: traceback.print_exc() K = np.array_str(calibration_res.K, precision=4, suppress_small=True) dist = calibration_res.distortion_info.data k1 = f"{dist.k1:4e}" k2 = f"{dist.k2:4e}" p1 = f"{dist.p1:4e}" p2 = f"{dist.p2:4e}" k3 = f"{dist.k3:4e}" imgs = [] i = 0 for d in display_images: d_encoded = str(base64.b64encode(d.data))[2:-1] d2 = { "id": i, "caption": f"Calibration image result {i+1}", "img": "data:image/jpeg;base64," + d_encoded } del d_encoded imgs.append(d2) i += 1 #TODO: check for png? dialog = js.Vue.new( js.python_to_js({ "el": "#new_calibrate_intrinsic_dialog2_wrapper", "template": dialog2_html, "data": { "K": K, "k1": k1, "k2": k2, "p1": p1, "p2": p2, "k3": k3, "display_images": imgs }, "methods": { "handle_hidden": handle_hidden } })) dialog["$bvModal"].show("new_vision_camera_calibrate_intrinsic2") except: traceback.print_exc()
def do_show_new_robot_origin_calibration_dialog2(new_name: str, robot_pose, display_images, core: "PyriWebUIBrowser"): try: dialog2_html = importlib_resources.read_text( __package__, "new_calibrate_robot_origin_dialog2.html") robot_calib = core.device_manager.get_device_subscription( "vision_robot_calibration").GetDefaultClient() geom_util = GeometryUtil(client_obj=robot_calib) marker_xyz, marker_rpy, _, _ = geom_util.named_pose_to_xyz_rpy( robot_pose.pose) el = js.document.createElement('div') el.id = "new_calibrate_robot_origin_dialog2_wrapper" js.document.getElementById("wrapper").appendChild(el) def handle_hidden(*args): try: el.parentElement.removeChild(el) except: traceback.print_exc() x = f"{marker_xyz[0]:4e}" y = f"{marker_xyz[1]:4e}" z = f"{marker_xyz[2]:4e}" r_r = f"{marker_rpy[0]:4e}" r_p = f"{marker_rpy[1]:4e}" r_y = f"{marker_rpy[2]:4e}" imgs = [] i = 0 for d in display_images: d_encoded = str(base64.b64encode(d.data))[2:-1] d2 = { "id": i, "caption": f"Calibration result {i+1}", "img": "data:image/jpeg;base64," + d_encoded } del d_encoded imgs.append(d2) i += 1 #TODO: check for png? dialog = js.Vue.new( js.python_to_js({ "el": "#new_calibrate_robot_origin_dialog2_wrapper", "template": dialog2_html, "data": { "x": x, "y": y, "z": z, "r_r": r_r, "r_p": r_p, "r_y": r_y, "display_images": imgs }, "methods": { "handle_hidden": handle_hidden } })) dialog["$bvModal"].show("new_vision_camera_calibrate_robot_origin2") except: traceback.print_exc()
async def do_show_new_robot_origin_calibration_dialog( new_name: str, variable_type: str, variable_tags: str, core: "PyriWebUIBrowser"): try: core.device_manager.connect_device("vision_robot_calibration") dialog_html = importlib_resources.read_text( __package__, "new_calibrate_robot_origin_dialog.html") dialog_obj = NewRobotOriginCalibrationDialog(new_name, core, core.device_manager) el = js.document.createElement('div') el.id = "new_calibrate_robot_origin_dialog_wrapper" js.document.getElementById("wrapper").appendChild(el) dialog = js.Vue.new( js.python_to_js({ "el": "#new_calibrate_robot_origin_dialog_wrapper", "template": dialog_html, "data": { "robot_selected": "", "robot_select_options": [], "camera_intrinsic_selected": "", "camera_intrinsic_select_options": [], "camera_extrinsic_selected": "", "camera_extrinsic_select_options": [], "image_sequence_selected": "", "image_sequence_select_options": [], "aruco_dict_selected": "", "aruco_dict_select_options": [], "aruco_tag_id": "120", "aruco_tag_size": "0.06", "marker_pose_x": "0", "marker_pose_y": "0", "marker_pose_z": "0", "marker_pose_r_r": "0", "marker_pose_r_p": "0", "marker_pose_r_y": "0", }, "methods": { "handle_create": dialog_obj.handle_create, "handle_hidden": dialog_obj.handle_hidden } })) dialog_obj.init_vue(dialog) robots = [] robot_names = util.get_devices_with_type( core, "com.robotraconteur.robotics.robot.Robot") robots = util.device_names_to_dropdown_options(robot_names) dialog["$data"].robot_select_options = js.python_to_js(robots) if len(robots) > 0: dialog["$data"].robot_selected = robots[0]["value"] db = core.device_manager.get_device_subscription( "variable_storage").GetDefaultClient() intrins_var_names = await db.async_filter_variables( "globals", "", ["camera_calibration_intrinsic"], None) intrins_vars = [] for v in intrins_var_names: intrins_vars.append({"value": v, "text": v}) dialog["$data"].camera_intrinsic_select_options = js.python_to_js( intrins_vars) if len(intrins_vars) > 0: dialog["$data"].camera_intrinsic_selected = intrins_vars[0][ "value"] extrins_var_names = await db.async_filter_variables( "globals", "", ["camera_calibration_extrinsic"], None) extrins_vars = [] for v in extrins_var_names: extrins_vars.append({"value": v, "text": v}) dialog["$data"].camera_extrinsic_select_options = js.python_to_js( extrins_vars) if len(extrins_vars) > 0: dialog["$data"].camera_extrinsic_selected = extrins_vars[0][ "value"] seq_var_names = await db.async_filter_variables( "globals", "", ["image_sequence"], None) seq_vars = [] for v in seq_var_names: seq_vars.append({"value": v, "text": v}) dialog["$data"].image_sequence_select_options = js.python_to_js( seq_vars) if len(seq_vars) > 0: dialog["$data"].image_sequence_selected = seq_vars[0]["value"] aruco_dicts = ['DICT_4X4_100', 'DICT_4X4_1000', 'DICT_4X4_250', \ 'DICT_4X4_50', 'DICT_5X5_100', 'DICT_5X5_1000', 'DICT_5X5_250', \ 'DICT_5X5_50', 'DICT_6X6_100', 'DICT_6X6_1000', 'DICT_6X6_250', \ 'DICT_6X6_50', 'DICT_7X7_100', 'DICT_7X7_1000', 'DICT_7X7_250', \ 'DICT_7X7_50', 'DICT_APRILTAG_16H5', 'DICT_APRILTAG_16h5', 'DICT_APRILTAG_25H9', \ 'DICT_APRILTAG_25h9', 'DICT_APRILTAG_36H10', 'DICT_APRILTAG_36H11', 'DICT_APRILTAG_36h10', \ 'DICT_APRILTAG_36h11', 'DICT_ARUCO_ORIGINAL'] aruco_opts = [{"value": v, "text": v} for v in aruco_dicts] dialog["$data"].aruco_dict_select_options = js.python_to_js(aruco_opts) dialog["$data"].aruco_dict_selected = 'DICT_6X6_250' dialog["$bvModal"].show("new_vision_camera_calibrate_robot_origin") except: js.alert(f"Calibration failed:\n\n{traceback.format_exc()}")
async def add_vision_panel(panel_type: str, core: PyriWebUIBrowser, parent_element: Any): print("#### add_vision_panel called") #assert panel_type == "" vision_panel_config = { "type": "stack", "componentName": "Vision", "componentState": {}, "title": "Vision", "id": "vision", "isClosable": False } core.layout.register_component("vision",False) core.layout.add_panel(vision_panel_config) core.layout.add_panel_menu_item("vision", "Vision") camera_list_panel_html = importlib_resources.read_text(__package__,"cameras_panel.html") camera_list_panel_config = { "type": "component", "componentName": "camera_list", "componentState": {}, "title": "Camera List", "id": "camera_list", "isClosable": False } def register_camera_list_panel(container, state): container.getElement().html(camera_list_panel_html) core.layout.register_component("camera_list",register_camera_list_panel) core.layout.layout.root.getItemsById("vision")[0].addChild(js.python_to_js(camera_list_panel_config)) camera_list_panel_obj = PyriCameraListPanel(core, core.device_manager) cameras_panel = js.Vue.new(js.python_to_js({ "el": "#cameras_table", "components": { "BootstrapTable": js.window.BootstrapTable }, "data": { "cameras": [], "cameras_columns": [ { "field": "local_device_name", "title": "Camera Device Name" }, { "field": "actions", "title": "Actions", "searchable": False, "formatter": lambda a,b,c,d: """ <a class="camera_list_open" title="Open Preview" @click="camera_open(c.local_device_name)"><i class="fas fa-2x fa-folder-open"></i></a> <a class="camera_list_info" title="Camera Info" @click="camera_info(c.local_device_name)"><i class="fas fa-2x fa-info-circle"></i></a> """ #<a class="camera_lest_settings" title="Camera Settings" @click="camera_settings(c.local_device_name)"><i class="fas fa-2x fa-cog"></i></a> , "events": { "click .camera_list_open": lambda e, value, row, d: camera_list_panel_obj.camera_open(row["local_device_name"]), "click .camera_list_info": lambda e, value, row, d: camera_list_panel_obj.camera_info(row["local_device_name"]) } }, ], "camera_list_options": { "search": True, "showColumns": False, "showToggle": True, "search": True, "showSearchClearButton": True, "showRefresh": False, "cardView": True, "toolbar": "#camera_list_toolbar" } }, "methods": { "camera_open": camera_list_panel_obj.camera_open, "camera_info": camera_list_panel_obj.camera_info, "camera_settings": camera_list_panel_obj.camera_settings, "refresh_cameras_table": camera_list_panel_obj.refresh_cameras_table } })) camera_list_panel_obj.init_vue(cameras_panel) camera_viewer_panel_html = importlib_resources.read_text(__package__,"camera_viewer_panel.html") def register_camera_viewer_panel(container, state): container.getElement().html(camera_viewer_panel_html) core.layout.register_component(f"camera_viewer",register_camera_viewer_panel) return None
async def add_devices_panel(panel_type: str, core: PyriWebUIBrowser, parent_element: Any): assert panel_type == "devices" devices_panel_html = importlib_resources.read_text(__package__, "devices_panel.html") panel_config = { "type": "component", "componentName": "devices", "componentState": {}, "title": "Devices", "id": "devices", "isClosable": False } def register_devices_panel(container, state): container.getElement().html(devices_panel_html) core.layout.register_component("devices", register_devices_panel) core.layout.add_panel(panel_config) core.layout.add_panel_menu_item("devices", "Devices") devices_panel_obj = PyriDevicesPanel(core.device_manager, core) devices_panel = js.Vue.new( js.python_to_js({ "el": "#active_devices_table", "components": { "BootstrapTable": js.window.BootstrapTable }, "data": { "active_device_names": [], "detected_devices": [], "selected_device_info": [], "device_list_columns": [{ "field": "select", "checkbox": True }, { "title": "Local Name", "field": "local_name" }, { "title": "Device Name", "field": "device_name", }, { "title": "Device Types", "field": "types" }, { "title": "Status", "field": "status", "formatter": lambda value, row, index, field: f"<span class=\"{'device_status_text_' + value}\"></span>" }, { "title": "State Flags", "field": "state_flags" }, { "title": "Action", "field": "actions", "searchable": False, "formatter": lambda a, b, c, d: """<a class="device_list_info" title="Device Info" @click=""><i class="fas fa-2x fa-info-circle"></i></a> <a class="device_list_remove" title="Remove Device" @click="device_remove(local_name)"><i class="fas fa-2x fa-trash"></i></a>""", "events": { "click .device_list_info": lambda e, value, row, d: devices_panel_obj.device_info( row["local_name"]), "click .device_list_remove": lambda e, value, row, d: devices_panel_obj. device_remove(row["local_name"]) } }], "device_list_options": { "search": False, "showColumns": False, "showToggle": True, "search": True, "showSearchClearButton": True, "showRefresh": False, "cardView": True, "toolbar": "#device_list_toolbar" }, "device_list": [], "add_device_columns": [{ "title": "Device", "field": "device" }, { "title": "Parent Device", "field": "parent_device", }, { "title": "Manufacturer", "field": "manufacturer" }, { "title": "Model", "field": "model" }, { "title": "Serial Number", "field": "serial_number" }, { "title": "User Description", "field": "user_description" }, { "title": "Service Name", "field": "service_name" }, { "title": "URLs", "field": "urls" }, { "title": "Root Object Type", "field": "root_object_type" }, { "title": "Root Object Implements", "field": "root_object_implements" }, { "title": "Action", "field": "action", "formatter": lambda a, b, c, d: '<a href="javascript:" class="device_panel_add_device"><i class="fas fs-4x fa-plus-circle"></i></a>', "events": { "click .device_panel_add_device": lambda e, value, row, d: devices_panel_obj. add_device_selected(row["device"]) } }], "selected_device_info_columns": [{ "title": "Device", "field": "device" }, { "title": "Parent Device", "field": "parent_device", }, { "title": "Manufacturer", "field": "manufacturer" }, { "title": "Model", "field": "model" }, { "title": "Serial Number", "field": "serial_number" }, { "title": "User Description", "field": "user_description" }, { "title": "Service Name", "field": "service_name" }, { "title": "URLs", "field": "urls" }, { "title": "Root Object Type", "field": "root_object_type" }, { "title": "Root Object Implements", "field": "root_object_implements" }], "add_device_options": { "search": True, "showSearchClearButton": True, "showToggle": True, "showColumns": False, "cardView": True, "showRefresh": False, "toolbar": "#add_device_toolbar" }, "selected_device_options": { "search": True, "showSearchClearButton": True, "showToggle": True, "showColumns": False, "cardView": True, "showRefresh": False } }, "methods": { "refresh_device_add": devices_panel_obj.refresh_device_add, "device_add": devices_panel_obj.device_add, "device_info": devices_panel_obj.device_info, "device_remove": devices_panel_obj.device_remove, "device_remove_selected": devices_panel_obj.device_remove_selected, "implemented_types": devices_panel_obj.implemented_types, } })) devices_panel_obj.init_vue(devices_panel) core.create_task(devices_panel_obj.run()) return devices_panel_obj
def add_panel(self, panel_config): self._layout.root.contentItems[0].addChild( js.python_to_js(panel_config))
async def run(self): await RRN.AsyncSleep(0.1, None) last_devices = set() device_table = [] while True: try: devices_states = self.core.devices_states new_devices = self.core.active_device_names table_updated = False if set(new_devices) != last_devices: #TODO: Remove old code # self.vue["$data"].active_device_names = js.python_to_js(new_devices) # last_devices = set(new_devices) # for d in last_devices: # try: # self.vue["$data"].device_names[d] = devices_states.devices_states[d].device.name # self.vue["$data"].device_state_flags[d] = util.device_state_flags(devices_states, d) # except: # pass last_devices = set(new_devices) new_table = [] for d in last_devices: d1 = { "local_name": d, "device_name": "", "types": "", "status": "disconnected", "state_flags": "", "select": False } try: d["device_name"] = devices_states.devices_states[ d].device.name d["device_state_flag"] = util.device_state_flags( devices_states, d) except: pass new_table.append(d1) self.vue["$data"].device_list = js.python_to_js(new_table) device_table = new_table table_updated = True if not table_updated: b_device_table = self.vue["$refs"].device_list for i in range(len(device_table)): t = device_table[i] d = t["local_name"] try: new_status = util.device_status_name( devices_states, d) if t["status"] != new_status: b_device_table.updateCell( js.python_to_js({ "index": i, "field": "status", "value": new_status })) t["status"] = new_status new_flags = util.device_state_flags( devices_states, d) if t["state_flags"] != new_flags: b_device_table.updateCell( js.python_to_js({ "index": i, "field": "state_flags", "value": new_flags })) t["state_flags"] = new_flags except: traceback.print_exc() try: d_name = devices_states.devices_states[ d].device.name if t["device_name"] != d_name: b_device_table.updateCell( js.python_to_js({ "index": i, "field": "device_name", "value": d_name })) t["device_name"] = d_name except: pass try: implemented_types = self.implemented_types(d) if t["types"] != implemented_types: b_device_table.updateCell( js.python_to_js({ "index": i, "field": "types", "value": implemented_types })) t["types"] = implemented_types except: traceback.print_exc() pass #new_flags[d] = "" #new_status[d] = "error" #self.vue["$data"].active_device_status = js.python_to_js(new_status) #self.vue["$data"].device_state_flags = js.python_to_js(new_flags) except: traceback.print_exc() self.vue["$data"].device_list = [] await RRN.AsyncSleep(0.5, None)