Example #1
0
def cancel_skills(misty: Misty) -> Dict:
    """Cancels all skills currently running on Misty.

    Args:
        misty (Misty): The Misty on which to cancel running skills.

    Returns:
        Dict: a dictionary with the key `overall_success` specifying whether all actions were successful and a key for every action containing the dictionarised Misty2pyResponse.
    """
    actions = ActionLog()
    data = misty.get_info("skills_running").parse_to_dict()
    actions.append_({"get_running_skills": data})

    data = data.get("rest_response", {})
    result = data.get("result", [])
    to_cancel = []
    for dct in result:
        uid = dct.get("uniqueId", "")
        if len(uid) > 0:
            to_cancel.append(uid)

    for skill in to_cancel:
        data = misty.perform_action("skill_cancel", data={
            "Skill": skill
        }).parse_to_dict()
        actions.append_({"cancel_%s" % skill: data})

    return success_of_action_list(actions.get_())
Example #2
0
 def drive_left(self, misty: Misty, velocity: int, angle: int):
     """Drives left with the specified velocity and angle."""
     left = {
         "LinearVelocity": self._parse_velocity(velocity),
         "AngularVelocity": self._parse_angle(angle),
     }
     return misty.perform_action("drive", data=left).parse_to_dict()
Example #3
0
def get_non_system_assets(
    misty: Misty,
    assets: List = ["audio", "image", "video", "recording"],
) -> Dict:
    """Obtains the list of all non-system assets that fall under one of the `assets` types.

    Args:
        misty (Misty): The Misty whose non system assets to obtain.
        assets (List, optional): The types of assets to obtain. Defaults to `["audio", "image", "video", "recording"]`.

    Returns:
        Dict: all non-system assets of a given type (keywords) listed as their names in the list under the type keyword.
    """
    action = "_list"
    non_sys_assets = {}
    for asset in assets:
        data = misty.get_info(asset + action).parse_to_dict()
        data = data.get("rest_response", {})
        result = data.get("result", [])
        for hit in result:
            name = hit.get("name")
            if not name:
                continue

            is_system = hit.get("systemAsset", True)
            if not is_system:
                if not non_sys_assets.get(asset):
                    non_sys_assets[asset] = []
                non_sys_assets[asset].append(name)
                print("Found a non-system asset of type `%s` named `%s`." %
                      (asset, name))

    return non_sys_assets
Example #4
0
def delete_assets(misty: Misty,
                  assets: Dict,
                  ignore_list: List = []) -> List[str]:
    """Deletes all non-system files except those that are in `ignore_list`.

    Args:
        misty (Misty): the Misty whose assets to delete.
        assets (Dict): The dictionary of assets; a list of file names under their asset type as the keyword.
        ignore_list (List, optional): The list of file names for files that should not be deleted. Defaults to `[]`.

    Returns:
        List[str]: The list of files that were succesfully deleted.
    """
    action = "_delete"
    delete_list = []

    for asset_type, files in assets.items():
        for file in files:
            if file not in ignore_list:
                if asset_type == "recording":
                    data = {"Name": file}
                else:
                    data = {"FileName": file}
                response = misty.perform_action(asset_type + action,
                                                data=data).parse_to_dict()
                response = response.get("rest_response", {})
                status = response.get("success")
                if status:
                    print("Successfully deleted the asset `%s`." % file)
                    delete_list.append(file)
                else:
                    print("Failed to delete the asset `%s`. Message: `%s`" %
                          (file, response))

    return delete_list
Example #5
0
 def drive_backward(self, misty: Misty, velocity: int):
     """Drives backwards with the specified velocity."""
     back = {
         "LinearVelocity": self._parse_velocity(velocity, negative=True),
         "AngularVelocity": self.stagnant_angle,
     }
     return misty.perform_action("drive", data=back).parse_to_dict()
Example #6
0
 def drive_forward(self, misty: Misty, velocity: int) -> Dict:
     """Drives forwards with the specified velocity."""
     forw = {
         "LinearVelocity": self._parse_velocity(velocity),
         "AngularVelocity": self.stagnant_angle,
     }
     return misty.perform_action("drive", data=forw).parse_to_dict()
Example #7
0
def get_misty(env_path: str = ".env") -> Callable:
    """Obtains a Misty instance using the `MISTY_IP_ADDRESS` in the supplied .env file."""
    from misty2py.robot import Misty
    from misty2py.utils.env_loader import EnvLoader

    env_loader = EnvLoader(get_abs_path(env_path))
    return Misty(env_loader.get_ip())
Example #8
0
 def drive_right(self, misty: Misty, velocity: int, angle: int):
     """Drives right with the specified velocity and angle."""
     velocity = self._parse_velocity(velocity)
     right = {
         "LinearVelocity": self._parse_velocity(velocity),
         "AngularVelocity": self._parse_angle(angle, negative=True),
     }
     return misty.perform_action("drive", data=right).parse_to_dict()
Example #9
0
def speak(misty: Misty, utterance: str) -> Dict:
    """Speaks an utterance and returns descriptive message.

    Args:
        misty (Misty): The Misty that speaks the utterance.
        utterance (str): The utterance to speak.

    Returns:
        Dict: the enhanced dictionarised Misty2pyResponse.
    """
    result = misty.perform_action(
        "speak",
        data={"Text": utterance, "UtteranceId": "utterance_" + get_random_string(6)},
    ).parse_to_dict()
    return compose_custom_response(
        result,
        success_message="Talking successful. Utterance: `%s`." % utterance,
        fail_message="Talking failed. Utterance: `%s`." % utterance,
    )
Example #10
0
def save_assets(misty: Misty, assets: Dict, location: str,
                overwrite: bool) -> List[str]:
    """Saves multiple assets.

    Args:
        misty (Misty): the Misty whose assets to save.
        assets (Dict): The dictionary of assets; a list of file names under their asset type as the keyword.
        location (str): The absolute path to the directory where the assets are saved.
        overwrite (bool): Whether the overwrite the file if it exists.

    Returns:
        List[str]: A list of file names for the files that failed to be saved.
    """
    failed_list = []
    action = "_file"
    for asset_type, files in assets.items():
        for file in files:
            params, name, ext = get_asset_properties(asset_type, file)
            response = misty.get_info(asset_type + action,
                                      params=params).parse_to_dict()
            response = response.get("rest_response", {})
            result = response.get("result")

            if not result:
                failed_list.append(file)

            else:
                file_name = "%s_%s_%s_in_base64.txt" % (asset_type, name, ext)
                full_path = os.path.join(location, file_name)
                file_content = result.get("base64")
                if not file_content:
                    failed_list.append(file)
                else:
                    success = save_base64_str(full_path, file_content,
                                              overwrite)
                    if not success:
                        failed_list.append(file)

    return failed_list
Example #11
0
def test_get_misty():
    from misty2py.robot import Misty

    m1 = get_misty()
    m2 = Misty(values.get("MISTY_IP_ADDRESS"))
    assert print(m1) == print(m2)
Example #12
0
import pytest
import time

from misty2py.basic_skills import (
    cancel_skills,
    expression,
    free_memory,
    movement,
    speak,
)
from misty2py.robot import Misty
from misty2py.utils.env_loader import EnvLoader

env_loader = EnvLoader()

MISTY = Misty(env_loader.get_ip())


def test_cancel_skills():
    result = cancel_skills.cancel_skills(MISTY)
    assert result.get("overall_success")


def test_free_memory():
    result = free_memory.free_memory(MISTY, overwrite=True)
    assert result.get("overall_success")


def test_speak():
    phrase = "Hello!"
    result = speak.speak(MISTY, phrase)
Example #13
0

DIR_NAME = path.abspath(path.dirname(__file__))

with open(path.join(DIR_NAME, "custom_allowed_actions.json")) as f:
    custom_allowed_infos = json.loads(f.read())
with open(path.join(DIR_NAME, "custom_allowed_data.json")) as f:
    custom_allowed_data = json.loads(f.read())
with open(path.join(DIR_NAME, "custom_allowed_infos.json")) as f:
    custom_allowed_actions = json.loads(f.read())

env_loader = EnvLoader()

MISTY = Misty(
    env_loader.get_ip(),
    custom_info=custom_allowed_infos,
    custom_actions=custom_allowed_actions,
    custom_data=custom_allowed_data,
)


def test_env_loader():
    env = EnvLoader(".env.example")
    assert env.get_ip() == "0.0.0.0"


def test_misty_print():
    assert str(MISTY) == "A Misty II robot with IP address %s" % env_loader.get_ip()


def test_basic_action_dict_method():
    colours = {"red": "200", "green": "20", "blue": "40"}
Example #14
0
def free_memory(
    misty: Misty,
    assets: List = ["audio", "image", "video", "recording"],
    save: bool = True,
    overwrite: bool = False,
    save_dir: str = "data",
) -> Dict:
    """Removes all non-system files in Misty's memory.

    Args:
        misty (Misty): the Misty whose memory to free.
        assets (List, optional): The list of asset types to delete. Defaults to `["audio", "image", "video", "recording"]`.
        save (bool, optional): Whether to save the files that are being deleted from Misty's memory. Defaults to `True`.
        overwrite (bool): Whether the overwrite the file if it exists. Defaults to `False`.
        save_dir (str, optional): The path to the directory that will store saved assets. Defaults to `"data"`.

    Returns:
        Dict: a dictionary with the key `overall_success` specifying whether all actions were successful and a key for every action containing the dictionarised Misty2pyResponse to that action.
    """
    save_dir = get_abs_path(save_dir)
    enable_audio = misty.perform_action("audio_enable").parse_to_dict()
    enable_av = misty.perform_action("streaming_av_enable").parse_to_dict()
    enable_camera = misty.perform_action("camera_enable").parse_to_dict()

    assets_to_delete = get_non_system_assets(misty, assets=assets)
    deletion = {}

    if len(assets_to_delete) == 0:
        deletion["success"] = True
        deletion["message"] = "No non-system files present."

    else:
        failed_to_save_list = []

        if save:
            failed_to_save_list = save_assets(misty, assets_to_delete,
                                              save_dir, overwrite)

        deleted = delete_assets(misty, assets_to_delete, failed_to_save_list)

        if len(deleted) > 0:
            deletion["success"] = True
            deletion[
                "message"] = "Successfully deleted following assets: %s" % str(
                    deleted)

        else:
            deletion["success"] = False
            deletion["message"] = "Failed to delete any assets."

    disable_audio = misty.perform_action("audio_disable").parse_to_dict()
    disable_av = misty.perform_action("streaming_av_disable").parse_to_dict()
    disable_camera = misty.perform_action("camera_disable").parse_to_dict()

    return success_of_action_dict(
        enable_audio=enable_audio,
        enable_av=enable_av,
        enable_camera=enable_camera,
        deletion={
            "overall_success": deletion["success"],
            "misty2py_response": deletion,
        },
        disable_audio=disable_audio,
        disable_av=disable_av,
        disable_camera=disable_camera,
    )
Example #15
0
 def stop_driving(self, misty: Misty):
     """Stops driving."""
     return misty.perform_action("drive_stop").parse_to_dict()
Example #16
0
def expression(
    misty: Misty,
    image: Union[str, Dict, None] = None,
    sound: Union[str, Dict, None] = None,
    colour_type: Union[str, None] = None,
    colour: Union[str, Dict, None] = None,
    colours: Union[str, Dict, None] = None,
    image_offset: Union[float, int] = 0,
    sound_offset: Union[float, int] = 0,
    colour_offset: Union[float, int] = 0,
    duration: Union[float, int] = 1.5,
) -> Dict:
    """Performs an audio-visual expression.

    Args:
        misty (Misty): the Misty that performs the expression.
        image (Union[str, Dict, None], optional): The path to the image to display or `None` if no special image should be displayed. Defaults to `None`.
        sound (Union[str, Dict, None], optional): The path to the sound to play or None if no sound should be played. Defaults to `None`.
        colour_type (Union[str, None], optional): `"trans"` if a colour transition should be lit. Defaults to `None`.
        colour (Union[str, Dict, None], optional): The colour of LED as a dictionary or a data shortcut or `None` if no special colour should be lit. Defaults to `None`.
        colours (Union[str, Dict, None], optional): The LED colours as a dictionary or a data shortcut or `None` if no transitioning colours should be lit. Defaults to `None`.
        image_offset (Union[float, int], optional): The offset between starting the expression and displaying the image in ms. Defaults to `0`.
        sound_offset (Union[float, int], optional): The offset between starting the expression and playing the sound in ms. Defaults to `0`.
        colour_offset (Union[float, int], optional): The offset between starting the expression and lighting the LEDs in ms. Defaults to `0`.
        duration (Union[float, int], optional): The duration of the expression. Defaults to `1.5`.

    Returns:
        Dict: a dictionary with the key `overall_success` specifying whether all actions were successful and a key for every action containing the dictionarised Misty2pyResponse for that action.
    """
    assert duration > 0, "Duration must be higher than zero."
    assert (colour_offset >= 0 and sound_offset >= 0
            and image_offset >= 0), "Offsets must be higher or equal to zero"
    assert (image or sound or colour
            or colours), "At least one audio-visual component \
        (display image, sound or led colour / colours) must be set."

    assert (image_offset < duration and sound_offset < duration
            and colour_offset < duration
            ), "The offsets cannot be higher than the duration."

    actions = ActionLog()

    reset_img = False
    reset_led = False

    offsets = sorted(set([image_offset, sound_offset, colour_offset]))
    for i, offset in enumerate(offsets):
        time.sleep(offset)

        if offset == image_offset:
            if image:
                img_show_message = misty.perform_action(
                    "image_show", data=image).parse_to_dict()
                actions.append_({"img_show": img_show_message})
                reset_img = True

        if offset == sound_offset:
            if sound:
                audio_play_message = misty.perform_action(
                    "audio_play", data=sound).parse_to_dict()
                actions.append_({"audio_play": audio_play_message})

        if offset == colour_offset:
            if colour_type == "trans":
                json_cols = None
                if colours:
                    json_cols = construct_transition_dict(
                        colours, misty.actions.allowed_data)
                elif colour:
                    json_cols = construct_transition_dict(
                        {
                            "col1": colour,
                            "col2": "led_off"
                        }, misty.actions.allowed_data)
                if json_cols:
                    led_trans_message = misty.perform_action(
                        "led_trans", data=json_cols).parse_to_dict()
                    actions.append_({"led_trans": led_trans_message})
                    reset_led = True
            else:
                if colour:
                    json_col = get_rgb_from_unknown(
                        colour, allowed_data=misty.actions.allowed_data)
                    led_message = misty.perform_action(
                        "led", data=json_col).parse_to_dict()
                    actions.append_({"led": led_message})
                    reset_led = True

        if i == len(offsets) - 1:
            time.sleep(duration - offset)

    if reset_img:
        reset_img_message = misty.perform_action(
            "image_show", data="image_content_default").parse_to_dict()
        actions.append_({"reset_img": reset_img_message})

    if reset_led:
        reset_led_message = misty.perform_action(
            "led", data="led_off").parse_to_dict()
        actions.append_({"reset_led": reset_led_message})

    return success_of_action_list(actions.get_())