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")
Beispiel #2
0
 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()}")
Beispiel #6
0
    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())
Beispiel #7
0
    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()
Beispiel #13
0
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()
Beispiel #14
0
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()}")
Beispiel #15
0
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>&nbsp;
                                                <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>&nbsp;
                                                """
                                                #<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>&nbsp;
                                                    <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
Beispiel #17
0
 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)