예제 #1
0
def packages_step() -> RespT:
    """Step to the next action.
    ---
    put:
      summary: Step to the next action.
      operationId: StepPackage
      tags:
        - Packages
      responses:
        200:
          description: Ok
        400:
          description: There is no paused package.
        500:
          description: Another error occurred.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
    """

    if not package_paused():
        return Response(status=400)

    resp = call_rpc(rpc.StepAction.Request(id=get_id()))

    if resp.result:
        return Response(status=200)
    else:
        return jsonify(resp.messages), 500
예제 #2
0
def packages_resume() -> RespT:
    """Resumes running package.
    ---
    put:
      summary: Resumes execution of the given package.
      operationId: ResumePackage
      tags:
        - Packages
      responses:
        200:
          description: Ok
        400:
          description: There is no paused package.
        500:
          description: Another error occurred.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
    """

    if not package_paused():
        return Response(status=400)

    resp = call_rpc(rpc.ResumePackage.Request(id=get_id()))

    if resp.result:
        return Response(status=200)
    else:
        return jsonify(resp.messages), 500
예제 #3
0
def package_debug(packageId: str) -> RespT:  # noqa
    """Debug project
    ---
    put:
      summary: Start debugging of the execution package.
      operationId: DebugPackage
      tags:
        - Packages
      parameters:
        - in: path
          name: packageId
          schema:
            type: string
          required: true
          description: The unique identification of the package.
        - in: query
          name: breakOnFirstAction
          schema:
            type: boolean
            default: false
          description: The project execution is paused before the first Action (default value is false).
      responses:
        200:
          description: The debugging process successfully started.
        400:
            description: Another package is active (running or paused).
        404:
          description:  The package cannot be found.
        500:
          description: Another error occurred.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
    """

    if not package_exists(packageId):
        return Response(status=404)

    if package_run_state():
        return Response(status=400)

    resp = call_rpc(
        rpc.RunPackage.Request(
            id=get_id(),
            args=rpc.RunPackage.Request.Args(
                packageId,
                request.args.get("breakOnFirstAction",
                                 default="false") == "true",
                breakpoints.get(packageId, None),
            ),
        ))

    if resp.result:
        return Response(status=200)
    else:
        return jsonify(resp.messages), 500
예제 #4
0
def unlock_object(ars: ARServer, obj_id: str) -> None:

    assert ars.call_rpc(
        rpc.lock.WriteUnlock.Request(
            get_id(), rpc.lock.WriteUnlock.Request.Args(obj_id)),
        rpc.lock.WriteUnlock.Response)

    event(ars, events.lk.ObjectsUnlocked)
예제 #5
0
def lock_object(ars: ARServer, obj_id: str, lock_tree: bool = False) -> None:

    assert ars.call_rpc(
        rpc.lock.WriteLock.Request(
            get_id(), rpc.lock.WriteLock.Request.Args(obj_id, lock_tree)),
        rpc.lock.WriteLock.Response,
    ).result

    event(ars, events.lk.ObjectsLocked)
예제 #6
0
async def run_temp_package(package_id: str, start_paused: bool = False, breakpoints: Optional[set[str]] = None) -> None:

    # TODO lock scene and project?

    assert glob.LOCK.scene
    assert glob.LOCK.project
    project_id = glob.LOCK.project.id
    glob.TEMPORARY_PACKAGE = True

    scene_online = scene_started()

    if scene_online:
        await stop_scene(glob.LOCK.scene)  # the package will start it on its own

    await project.close_project(show_mainscreen_after_that=False)
    req = erpc.RunPackage.Request
    exe_req = req(get_id(), args=req.Args(package_id, start_paused, breakpoints))
    exe_resp = await manager_request(exe_req)

    if not exe_resp.result:
        logger.warning(f"Execution of temporary package failed with: {exe_resp.messages}.")
    else:
        await server_events.package_started.wait()
        await server_events.package_stopped.wait()
        logger.info("Temporary package stopped, let's remove it and reopen project.")

    glob.TEMPORARY_PACKAGE = False

    await manager_request(erpc.DeletePackage.Request(get_id(), args=rpc.common.IdArgs(package_id)))

    await project.open_project(project_id)

    assert glob.LOCK.scene
    assert glob.LOCK.project

    await notif.broadcast_event(
        sevts.p.OpenProject(sevts.p.OpenProject.Data(glob.LOCK.scene.scene, glob.LOCK.project.project))
    )

    if scene_online:
        await start_scene(glob.LOCK.scene)
예제 #7
0
def ars() -> Iterator[ARServer]:

    with ARServer(ars_connection_str(),
                  timeout=30,
                  event_mapping=event_mapping) as ws:
        test_username = "******"
        assert ws.call_rpc(
            rpc.u.RegisterUser.Request(
                get_id(), rpc.u.RegisterUser.Request.Args(test_username)),
            rpc.u.RegisterUser.Response,
        ).result
        yield ws
예제 #8
0
def add_logic_item(
        ars: ARServer,
        start: str,
        end: str,
        condition: Optional[common.ProjectLogicIf] = None) -> common.LogicItem:

    assert ars.call_rpc(
        rpc.p.AddLogicItem.Request(
            get_id(), rpc.p.AddLogicItem.Request.Args(start, end, condition)),
        rpc.p.AddLogicItem.Response,
    ).result

    evt = event(ars, events.p.LogicItemChanged)
    assert evt.data
    return evt.data
예제 #9
0
def package_start(packageId: str) -> RespT:  # noqa
    """Run project
    ---
    put:
      summary: Start execution of the execution package.
      operationId: StartPackage
      tags:
        - Packages
      parameters:
        - in: path
          name: packageId
          schema:
            type: string
          required: true
          description: Unique package Id
      responses:
        200:
          description: Ok
        400:
            description: Another package is active (running or paused).
        404:
          description: Package not found
        500:
          description: Another error occurred.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
    """

    if not package_exists(packageId):
        return Response(status=404)

    if package_run_state():
        return Response(status=400)

    resp = call_rpc(
        rpc.RunPackage.Request(id=get_id(),
                               args=rpc.RunPackage.Request.Args(id=packageId)))

    if resp.result:
        breakpoints.pop(packageId, None)
        return Response(status=200)
    else:
        return jsonify(resp.messages), 500
예제 #10
0
def delete_package(packageId: str) -> RespT:  # noqa
    """Delete package.
    ---
    delete:
      summary: Delete package.
      operationId: DeletePackage
      tags:
        - Packages
      parameters:
        - in: path
          name: packageId
          description: Unique package Id
          schema:
            type: string
          required: true
          description: unique ID
      responses:
        200:
          description: Ok
        404:
          description: Package not found
        500:
          description: Another error occurred.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
    """

    if not package_exists(packageId):
        return Response(status=404)

    resp = call_rpc(
        rpc.DeletePackage.Request(id=get_id(),
                                  args=arcor2_rpc.common.IdArgs(id=packageId)))

    if resp.result:
        breakpoints.pop(packageId, None)
        return Response(status=200)
    else:
        return jsonify(resp.messages), 500
예제 #11
0
async def build_and_upload_package(project_id: str, package_name: str) -> str:
    """Builds package and uploads it to the Execution unit.

    :param project_id:
    :param package_name:
    :return: generated package ID.
    """

    package_id = common.uid("pkg")

    # call build service
    # TODO store data in memory
    async with tempfile.TemporaryDirectory() as tmpdirname:
        path = os.path.join(tmpdirname, "publish.zip")

        await hlp.run_in_executor(
            rest.download,
            f"{BUILD_URL}/project/{project_id}/publish",
            path,
            {"packageName": package_name},
        )

        async with aiofiles.open(path, "rb") as zip_file:
            b64_bytes = base64.b64encode(await zip_file.read())
            b64_str = b64_bytes.decode()

    # send data to execution service
    exe_req = erpc.UploadPackage.Request(get_id(), args=erpc.UploadPackage.Request.Args(package_id, b64_str))
    exe_resp = await manager_request(exe_req)

    if not exe_resp.result:
        if not exe_resp.messages:
            raise Arcor2Exception("Upload to the Execution unit failed.")
        raise Arcor2Exception("\n".join(exe_resp.messages))

    return package_id
예제 #12
0
def get_packages() -> RespT:
    """Gets summary for all stored execution packages.
    ---
    get:
      summary: Gets summary for all stored execution packages.
      operationId: GetSummaryPackages
      tags:
        - Packages
      responses:
        200:
          description: Summary of all packages on execution service.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: SummaryPackage
    """

    resp = call_rpc(rpc.ListPackages.Request(id=get_id()))
    assert isinstance(resp, rpc.ListPackages.Response)

    ret: list[dict] = []

    for pck in resp.data:
        sp = SummaryPackage(pck.id)
        sp.name = pck.package_meta.name
        sp.created = pck.package_meta.built
        sp.executed = pck.package_meta.executed
        if pck.project_meta:
            sp.project = SummaryProject(pck.project_meta.id,
                                        pck.project_meta.name,
                                        pck.project_meta.description)
        ret.append(sp.to_dict())

    return jsonify(ret), 200
예제 #13
0
    def __init__(
        self,
        ws_connection_str: str = "ws://0.0.0.0:6789",
        timeout: float = 3.0,
        event_mapping: Optional[dict[str, type[events.Event]]] = None,
    ):

        self._ws = websocket.WebSocket()
        self._logger = get_logger(__name__)
        self._event_queue: Queue[events.Event] = Queue()
        if event_mapping is None:
            event_mapping = {}

        self.event_mapping = event_mapping

        start_time = time.monotonic()
        while time.monotonic() < start_time + timeout:
            try:
                self._ws.connect(ws_connection_str)
                break
            except ConnectionRefusedError:
                time.sleep(0.25)

        if not self._ws.connected:
            raise ARServerClientException(f"Failed to connect to '{ws_connection_str}'.")

        self._ws.settimeout(timeout)

        system_info = self._call_rpc(srpc.c.SystemInfo.Request(get_id()), srpc.c.SystemInfo.Response).data

        if system_info is None:
            raise ARServerClientException("Failed to get SystemInfo.")

        self._logger.info(f"Connected to server version {system_info.version}.")

        self._supported_rpcs = system_info.supported_rpc_requests
예제 #14
0
def project(ars: ARServer, scene: common.Scene) -> common.Project:
    """Creates project with following objects:

    ap - global AP
    ap_ap - child of ap
    ap_ap_ap - child of ap_ap
    ori - ap_ap_ap orientation
    """

    test = "Test project"

    assert ars.call_rpc(
        rpc.p.NewProject.Request(
            get_id(), rpc.p.NewProject.Request.Args(scene.id, test, test)),
        rpc.p.NewProject.Response,
    ).result

    project_evt = event(ars, events.p.OpenProject)
    assert project_evt.data

    event(ars, events.s.SceneState)

    assert ars.call_rpc(
        rpc.p.AddActionPoint.Request(
            get_id(),
            rpc.p.AddActionPoint.Request.Args("ap", common.Position(0, 0, 0))),
        rpc.p.AddActionPoint.Response,
    ).result
    ap_evt = event(ars, events.p.ActionPointChanged)
    assert ap_evt.data

    assert ars.call_rpc(
        rpc.p.AddActionPoint.Request(
            get_id(),
            rpc.p.AddActionPoint.Request.Args("ap_ap",
                                              common.Position(0, 0, 1),
                                              ap_evt.data.id)),
        rpc.p.AddActionPoint.Response,
    ).result
    ap_ap_evt = event(ars, events.p.ActionPointChanged)
    assert ap_ap_evt.data

    assert ars.call_rpc(
        rpc.p.AddActionPoint.Request(
            get_id(),
            rpc.p.AddActionPoint.Request.Args("ap_ap_ap",
                                              common.Position(0, 0, 2),
                                              ap_ap_evt.data.id)),
        rpc.p.AddActionPoint.Response,
    ).result
    ap_ap_ap_evt = event(ars, events.p.ActionPointChanged)
    assert ap_ap_ap_evt.data

    lock_object(ars, ap_ap_ap_evt.data.id)

    assert ars.call_rpc(
        rpc.p.AddActionPointOrientation.Request(
            get_id(),
            rpc.p.AddActionPointOrientation.Request.Args(
                ap_ap_ap_evt.data.id, common.Orientation(), "ori")),
        rpc.p.AddActionPointOrientation.Response,
    ).result
    ori_evt = event(ars, events.p.OrientationChanged)
    assert ori_evt.data

    unlock_object(ars, ap_ap_ap_evt.data.id)

    assert ars.call_rpc(rpc.p.SaveProject.Request(get_id()),
                        rpc.p.SaveProject.Response).result
    event(ars, events.p.ProjectSaved)
    assert ars.call_rpc(rpc.p.CloseProject.Request(get_id()),
                        rpc.p.CloseProject.Response).result
    event(ars, events.p.ProjectClosed)
    event(ars, events.c.ShowMainScreen)

    return project_evt.data.project
예제 #15
0
def put_package(packageId: str) -> RespT:  # noqa
    """Put package
    ---
    put:
        summary: Adds the execution package.
        operationId: PutPackage
        tags:
           - Packages
        parameters:
            - in: path
              name: packageId
              schema:
                type: string
              required: true
              description: Unique package Id
        requestBody:
              content:
                multipart/form-data:
                  schema:
                    type: object
                    required:
                        - executionPackage
                    properties:
                      # 'file' will be the field name in this multipart request
                      executionPackage:
                        type: string
                        format: binary
        responses:
            200:
              description: Ok
            500:
              description: Another error occurred.
              content:
                application/json:
                  schema:
                    type: array
                    items:
                      type: string
    """

    file = request.files["executionPackage"]
    assert file.filename
    file_name = secure_filename(file.filename)

    with tempfile.TemporaryDirectory() as tmpdirname:
        file_path = os.path.join(tmpdirname, file_name)
        file.save(file_path)

        with open(file_path, "rb") as zip_file:
            b64_bytes = base64.b64encode(zip_file.read())
            b64_str = b64_bytes.decode()

    resp = call_rpc(
        rpc.UploadPackage.Request(id=get_id(),
                                  args=rpc.UploadPackage.Request.Args(
                                      packageId, b64_str)))

    if resp.result:
        return Response(status=200)
    else:
        return jsonify(resp.messages), 500
예제 #16
0
def scene(ars: ARServer) -> common.Scene:

    assert isinstance(ars.get_event(), events.c.ShowMainScreen)

    test = "Test scene"

    assert ars.call_rpc(
        rpc.s.NewScene.Request(get_id(),
                               rpc.s.NewScene.Request.Args(test, test)),
        rpc.s.NewScene.Response).result

    scene_evt = event(ars, events.s.OpenScene)
    assert scene_evt.data

    event(ars, events.s.SceneState)

    test_type = "TestType"

    assert ars.call_rpc(
        rpc.o.NewObjectType.Request(
            get_id(), objects.ObjectTypeMeta(test_type,
                                             base=Generic.__name__)),
        rpc.o.NewObjectType.Response,
    ).result

    tt_evt = event(ars, events.o.ChangedObjectTypes)

    assert len(tt_evt.data) == 1
    assert not tt_evt.data[0].has_pose
    assert tt_evt.data[0].type == test_type
    assert tt_evt.data[0].base == Generic.__name__

    assert ars.call_rpc(
        rpc.s.AddObjectToScene.Request(
            get_id(),
            rpc.s.AddObjectToScene.Request.Args("test_type", test_type)),
        rpc.s.AddObjectToScene.Response,
    ).result

    event(ars, events.s.SceneObjectChanged)

    test_type_with_pose = "TestTypeWithPose"

    assert ars.call_rpc(
        rpc.o.NewObjectType.Request(
            get_id(),
            objects.ObjectTypeMeta(test_type_with_pose,
                                   base=GenericWithPose.__name__)),
        rpc.o.NewObjectType.Response,
    ).result

    ttwp_evt = event(ars, events.o.ChangedObjectTypes)
    assert len(ttwp_evt.data) == 1
    assert ttwp_evt.data[0].has_pose
    assert ttwp_evt.data[0].type == test_type_with_pose
    assert ttwp_evt.data[0].base == GenericWithPose.__name__

    assert ars.call_rpc(
        rpc.s.AddObjectToScene.Request(
            get_id(),
            rpc.s.AddObjectToScene.Request.Args("test_type_with_pose",
                                                test_type)),
        rpc.s.AddObjectToScene.Response,
    ).result

    event(ars, events.s.SceneObjectChanged)

    assert ars.call_rpc(rpc.s.SaveScene.Request(get_id()),
                        rpc.s.SaveScene.Response).result
    event(ars, events.s.SceneSaved)
    assert ars.call_rpc(rpc.s.CloseScene.Request(get_id()),
                        rpc.s.CloseScene.Response).result
    event(ars, events.s.SceneClosed)
    event(ars, events.c.ShowMainScreen)

    return scene_evt.data.scene
예제 #17
0
def test_object_parameters(start_processes: None, ars: ARServer,
                           scene: Scene) -> None:

    assert ars.call_rpc(rpc.s.OpenScene.Request(get_id(), IdArgs(scene.id)),
                        rpc.s.OpenScene.Response).result

    event(ars, events.s.OpenScene)
    event(ars, events.s.SceneState)

    assert ars.call_rpc(
        rpc.s.AddObjectToScene.Request(
            get_id(),
            rpc.s.AddObjectToScene.Request.Args("ows",
                                                ObjectWithActions.__name__)),
        rpc.s.AddObjectToScene.Response,
    ).result

    obj = event(ars, events.s.SceneObjectChanged).data
    assert obj is not None

    assert ars.call_rpc(
        rpc.p.NewProject.Request(
            get_id(), rpc.p.NewProject.Request.Args(scene.id, "Project name")),
        rpc.p.NewProject.Response,
    ).result

    event(ars, events.s.SceneSaved)
    event(ars, events.p.OpenProject)
    event(ars, events.s.SceneState)

    assert ars.call_rpc(
        rpc.p.AddActionPoint.Request(
            get_id(), rpc.p.AddActionPoint.Request.Args("ap", Position())),
        rpc.p.AddActionPoint.Response,
    ).result

    ap = event(ars, events.p.ActionPointChanged).data
    assert ap is not None

    assert ars.call_rpc(
        rpc.p.AddAction.Request(
            get_id(),
            rpc.p.AddAction.Request.Args(
                ap.id,
                "a1",
                f"{obj.id}/{ObjectWithActions.bool_action.__name__}",
                [],
                [Flow(outputs=["bool_result"])],
            ),
        ),
        rpc.p.AddAction.Response,
    ).result

    a1 = event(ars, events.p.ActionChanged).data
    assert a1 is not None

    assert ars.call_rpc(
        rpc.p.AddAction.Request(
            get_id(),
            rpc.p.AddAction.Request.Args(
                ap.id,
                "a2",
                f"{obj.id}/{ObjectWithActions.str_action.__name__}",
                [],
                [Flow()],
            ),
        ),
        rpc.p.AddAction.Response,
    ).result

    a2 = event(ars, events.p.ActionChanged).data
    assert a2 is not None

    add_logic_item(ars, LogicItem.START, a1.id)
    event(ars, events.lk.ObjectsUnlocked)

    lock_object(ars, a1.id)
    add_logic_item(
        ars, a1.id, a2.id,
        ProjectLogicIf(f"{a1.id}/{FlowTypes.DEFAULT}/{0}", json.dumps(True)))
    event(ars, events.lk.ObjectsUnlocked)

    lock_object(ars, a2.id)
    add_logic_item(ars, a2.id, LogicItem.END)
    event(ars, events.lk.ObjectsUnlocked)

    lock_object(ars, a1.id)
    add_logic_item(
        ars, a1.id, LogicItem.END,
        ProjectLogicIf(f"{a1.id}/{FlowTypes.DEFAULT}/{0}", json.dumps(False)))
    event(ars, events.lk.ObjectsUnlocked)

    # TODO try to add some invalid connections here?

    save_project(ars)
예제 #18
0
def close_project(ars: ARServer) -> None:

    assert ars.call_rpc(rpc.p.CloseProject.Request(get_id()),
                        rpc.p.CloseProject.Response).result
    event(ars, events.p.ProjectClosed)