# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['misty2py', 'misty2py.basic_skills', 'misty2py.utils']

package_data = \
{'': ['*']}

install_requires = \
['python-dotenv>=0.17.1,<0.18.0',
 'requests>=2.25.1,<3.0.0',
 'websocket-client>=0.58.0,<0.59.0']

setup_kwargs = {
    'name': 'misty2py',
    'version': '4.1.5',
    'description': 'A Python library for Misty II development',
    'long_description': '# Misty2py\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) [![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/ChrisScarred/misty2py/blob/main/LICENSE)\n\nMisty2py is a Python 3 library for Misty II development using [Misty API](https://docs.mistyrobotics.com/misty-ii/rest-api/api-reference/ "Misty Robotics REST API").\n\n## Features\n\nMisty2py can be used to develop complex skills (behaviours) for the Misty II robot utilising:\n\n- **actions** via sending a `POST` or `DELETE` requests to Misty\'s API;\n- **informations** via sending a `GET` request to Misty\'s API;\n- **continuous streams of data** via subscribing to event types on Misty\'s websockets.\n\nMisty2py uses following concepts for easy of usage:\n\n- **action keywords** - customisable python-styled keywords for endpoints of Misty\'s API that correspond to performing actions;\n- **information keywords** - customisable python-styled keywords for endpoints of Misty\'s API that correspond to retrieving information;\n- **data shortcuts** - customisable python-styled keywords for commonly used data that are supplied to Misty\'s API as the body of a `POST` request.\n\n## Usage\n\n### Getting started\n\n- Start by making **a new instance** of `misty2py.robot`\'s `Misty` by `misty_robot = Misty("ip_address_here")`\n  - Substitute `ip_address_here` with the IP address of your Misty.\n  - `misty2py.utils.env_loader` module contains `EnvLoader` class that can be used to load Misty\'s IP from the .env file in your project\'s home directory:\n    - Create the `.env` file and write `MISTY_IP_ADDRESS="[ip_address_here]"` in it.\n    - Initialise an `EnvLoader` object via `env_loader = EnvLoader()`; this loads the environment variables.\n    - Use `env_loader.get_ip()` to obtain the IP address.\n- Use the method `misty_robot.perform_action()` to tell Misty to **perform an action**.\n- Use the method `misty_robot.get_info()` to tell Misty to **return information**.\n- Use the method `misty_robot.event()` to initialise, obtain and stop **continuous streams of data** from Misty\'s event types.\n\n### Obtaining information\n\nObtaining digital information is handled by `misty2py.robot::get_info` method.\n\n`misty2py.robot::get_info` has following arguments:\n\n- `info_name` - *required;* the string information keyword corresponding to an endpoint in Misty\'s API;\n- `params` - *optional;* a dictionary of parameter name and parameter value pairs, defaults to `{}`.\n\n### Performing actions\n\nPerforming physical and digital actions including removal of non-system files is handled by `misty2py.robot::perform_action()` method.\n\n`misty2py.robot::perform_action()` has following arguments:\n\n- `action_name` - *required;* the string action keyword corresponding to an endpoint in Misty\'s API;\n- `data` - *optional;* the data to pass to the request as a dictionary or a data shortcut (string), defaults to `{}`.\n\n### Event types\n\nTo obtain event data in Misty\'s framework, it is required to **subscribe** to an event type on Misty\'s websocket server. Misty\'s websocket server then streams data to the websocket client, in this implementation via a separate thread. To **access this data,** `misty2py.robot::event` method must be called with `"get_data"` parameter from the main thread. When data are no longer required to be streamed to the client, an event type can be **unsubscribed** to kill the event thread.\n\n#### Subscription\n\nSubscribe to an event via `misty2py.robot::event` with the parameter `"subscribe"` and following keyword arguments:\n\n    - `type` - *required;* event type string as documented in [Event Types Docs](https://docs.mistyrobotics.com/misty-ii/robot/sensor-data/ "Misty Robotics Event Types").\n    - `name` - *optional;* a custom event name string; must be unique.\n    - `return_property` - *optional;* the property to return from Misty\'s websockets; all properties are returned if return_property is not supplied.\n    - `debounce` - *optional;* the interval in ms at which new information is sent; defaults to 250.\n    - `len_data_entries` - *optional;* the maximum number of data entries to keep (discards in fifo style); defaults to 10.\n    - `event_emitter` - *optional;* an event emitter function which emits an event upon message recieval. Supplies the message content as an argument.\n\n#### Accessing the data and the log\n\nAccess the data of an event or its log via `misty2py.robot::event` with the parameter `"get_data"` or `"get_log"` and a keyword argument `name` (the name of the event).\n\n#### Unsubscribing\n\nUnsubscribe from an event via `misty2py.robot::event` with the parameter `"unsubscribe"` and a keyword argument `name` (the name of the event).\n\n#### Basic example\n\n```python\nimport time\n\nfrom misty2py.robot import Misty\nfrom misty2py.utils.env_loader import EnvLoader\n\nenv_loader = EnvLoader\n\nm = Misty(env_loader.get_ip())\n\nd = m.event("subscribe", type = "BatteryCharge")\ne_name = d.get("event_name")\n\ntime.sleep(1)\n\nd = m.event("get_data", name = e_name)\n\nd = m.event("unsubscribe", name = e_name)\n```\n\n#### Event emitter usage - example\n\n```python\nimport time\nfrom pymitter import EventEmitter\n\nfrom misty2py.robot import Misty\nfrom misty2py.utils.env_loader import EnvLoader\n\nenv_loader = EnvLoader\n\nm = Misty(env_loader.get_ip())\nee = EventEmitter()\nevent_name = "myevent_001"\n\n@ee.on(event_name)\ndef listener(data):\n    print(data)\n\nd = m.event("subscribe", type = "BatteryCharge", name = event_name, event_emitter = ee)\n\ntime.sleep(2)\n\nd = m.event("unsubscribe", name = event_name)\n```\n\n### Utilities\n\nThe sub-package `misty2py.utils` contains utility modules, including:\n\n- `misty2py.utils.base64` - contains base64 encoders and decoders.\n  - `misty2py.utils.base64::content_to_base64` - encodes a string or a file into base64 string and either returns the encoded string or saves the encoded string into a file.\n  - `misty2py.utils.base64::base64_to_content` - decodes a string or a file from base64 and either returns the decoded string or saves the decoded file.\n\n- `misty2py.utils.colours` - contains colour-related utility functions.\n  - `misty2py.utils.colours::parse_rgb_value` - parses and validates a potentially rgb value (a string or an integer).\n  - `misty2py.utils.colours::rgb_values_to_dict` - turns integer or string triple of rgb values into the rgb dictionary form required by Misty API.\n  - `misty2py.utils.colours::validate_rgb_dict` - validates an rgb dictionary.\n  - `misty2py.utils.colours::get_rgb_from_unknown` - attempts to obtain an rgb dictionary from an unknown data content (possibly a data shortcut or a dictionary)\n  - `misty2py.utils.colours::construct_transition_dict` - constructs the transition dictionary as required by Misty API from a dictionary of two colours supplied either as data shortcuts or rgb dictionaries.\n\n- `misty2py.utils.env_loader` contains the `EnvLoader` class which can be used to load environmental variables, specifically the IP address of the Misty robot.\n  - `misty2py.utils.env_loader::EnvLoader.__init__` (aka `misty2py.utils.env_loader.EnvLoader()`) - initialises the `EnvLoader`, takes optional argument `env_path` (str) for a custom path to the `.env` file.\n  - `misty2py.utils.env_loader::EnvLoader.get_ip` - obtains the value of the environmental variable `MISTY_IP_ADDRESS` if set, else returns `None`.\n\n- `misty2py.utils.generators` - contains generator functions.\n  - `misty2py.utils.generators::get_random_string` - returns a random `n` characters long string of ASCII letters and digits\n\n- `misty2py.utils.messages` - contains message parsing methods.\n  - `misty2py.utils.messages::message_parser` - parses a message from misty2py json Dict reply to a string.\n  - `misty2py.utils.messages::compose_str` - adds `potential_str` to `main_str` if `potential_str` is not `None`, else adds `fallback` to `main_str` if `fallback` is not `None`, else returns `main_str`\n\n- `misty2py.utils.utils` - contains generally useful functions that do not fall into any of the above categories.\n  - `misty2py.utils.utils::query_dict_with_fallback` - safely queries a dictionary and if the key does not exist or the value has inappropriate type, returns the fallback value.\n\n### Keywords and shortcuts\n\n<details> \n  <summary>List of supported action keywords</summary>\n  \n- `led` for **post** request to `api/led` endpoint\n- `led_trans` for **post** request to `api/led/transition` endpoint\n- `notification_settings` for **post** request to `api/notification/settings` endpoint\n- `audio_upload` for **post** request `api/audio` to endpoint\n- `audio_play` for **post** request to `api/audio/play` endpoint\n- `audio_pause` for **post** request to `api/audio/pause` endpoint\n- `audio_stop` for **post** request to `api/audio/stop` endpoint\n- `audio_delete` for **delete** request to `api/audio` endpoint\n- `audio_record_start` for **post** request to `api/audio/record/start` endpoint\n- `audio_record_stop` for **post** request to `api/audio/record/stop` endpoint\n- `audio_disable` for **post** request to `api/services/audio/disable` endpoint\n- `audio_enable` for **post** request to `api/services/audio/enable` endpoint\n- `image_upload` for **post** request to `api/images` endpoint\n- `image_show` for **post** request to `api/images/display` endpoint\n- `image_settings` for **post** request to `api/images/settings` endpoint\n- `image_delete` for **delete** request to `api/images` endpoint\n- `text_show` for **post** request to `api/text/display` endpoint\n- `text_settings` for **post** request to `api/text/settings` endpoint\n- `video_upload` for **post** request to `api/videos` endpoint\n- `video_show` for **post** request to `api/videos/display` endpoint\n- `video_settings` for **post** request to `api/videos/settings` endpoint\n- `video_delete` for **delete** request to `api/videos` endpoint\n- `blink_mapping_delete` for **delete** request to `api/blink/images` endpoint\n- `slam_enable` for **post** request to `api/services/slam/enable` endpoint\n- `slam_disable` for **post** request to `api/services/slam/disable` endpoint\n- `slam_sensors_reset` for **post** request to `api/slam/reset` endpoint\n- `slam_mapping_start` for **post** request to `api/slam/map/start` endpoint\n- `slam_mapping_stop` for **post** request to `api/slam/map/stop` endpoint\n- `slam_map_current` for **post** request to `api/slam/map/current` endpoint\n- `slam_map_rename` for **post** request to `api/slam/map/rename` endpoint\n- `slam_infrared_settings` for **post** request to `api/slam/settings/ir` endpoint\n- `slam_visible_settings` for **post** request to `api/slam/settings/visible` endpoint\n- `slam_map_delete` for **delete** request to `api/slam/map` endpoint\n- `slam_docking_locate_start` for **post** request to `api/slam/docking/start` endpoint\n- `slam_docking_locate_stop` for **post** request to `api/slam/docking/stop` endpoint\n- `streaming_slam_start` for **post** request to `api/slam/streaming/start` endpoint\n- `streaming_slam_stop` for **post** request to `api/slam/streaming/stop` endpoint\n- `slam_track_start` for **post** request to `api/slam/track/start` endpoint\n- `slam_track_stop` for **post** request to `api/slam/track/stop` endpoint\n- `recording_start` for **post** request to `api/videos/recordings/start` endpoint\n- `recording_stop` for **post** request to `api/videos/recordings/stop` endpoint\n- `recording_rename` for **post** request to `api/videos/recordings/rename` endpoint\n- `recording_delete` for **delete** request to `api/videos/recordings` endpoint\n- `face_detection_start` for **post** request to `api/faces/detection/start` endpoint\n- `face_detection_stop` for **post** request to `api/faces/detection/stop` endpoint\n- `face_recognition_start` for **post** request to `api/faces/recognition/start` endpoint\n- `face_recognition_stop` for **post** request to `api/faces/recognition/stop` endpoint\n- `face_train_start` for **post** request to `api/faces/training/start` endpoint\n- `face_train_cancel` for **post** request to `api/faces/training/cancel` endpoint\n- `face_delete` for **delete** request to `api/faces` endpoint\n- `skill_upload` for **post** request to `api/skills` endpoint\n- `skill_start` for **post** request to `api/skills/start` endpoint\n- `skills_reload` for **post** request to `api/skills/reload` endpoint\n- `skill_load` for **post** request to `api/skills/load` endpoint\n- `skill_cancel` for **post** request to `api/skills/cancel` endpoint\n- `skill_delete` for **delete** request to `api/skills` endpoint\n- `wifi_add` for **post** request to `api/networks/create` endpoint\n- `wifi_connect` for **post** request to `api/networks` endpoint\n- `wifi_delete` for **delete** request to `api/networks` endpoint\n- `wifi_hotspot_start` for **post** request to `api/networks/hotspot/start` endpoint\n- `wifi_hotspot_stop` for **post** request to `api/networks/hotspot/stop` endpoint\n- `write_serial` for **post** request to `api/serial` endpoint\n- `event_listener` for **post** request to `api/skills/event` endpoint\n- `website_show` for **post** request to `api/webviews/display` endpoint\n- `website_settings` for **post** request to `api/webviews/settings` endpoint\n- `blink_on` for **post** request to `api/blink` endpoint\n- `blink_settings` for **post** request to `api/blink/settings` endpoint\n- `display_settings` for **post** request to `api/display/settings` endpoint\n- `flashlight_on` for **post** request to `api/flashlight` endpoint\n- `speak` for **post** request to `api/tts/speak` endpoint\n- `speak_stop` for **post** request to `api/tts/stop` endpoint\n- `speech_capture` for **post** request to `api/audio/speech/capture` endpoint\n- `drive` for **post** request to `api/drive` endpoint\n- `drive_arc` for **post** request to `api/drive/arc` endpoint\n- `drive_heading` for **post** request to `api/drive/hdt` endpoint\n- `drive_time` for **post** request to `api/drive/time` endpoint\n- `drive_track` for **post** request to `api/drive/track` endpoint\n- `drive_stop` for **post** request to `api/drive/stop` endpoint\n- `drive_to_loc` for **post** request to `api/drive/coordinates` endpoint\n- `drive_on_path` for **post** request to `api/drive/path` endpoint\n- `halt` for **post** request to `api/halt` endpoint\n- `arm_move` for **post** request to `api/arms` endpoint\n- `arms_move` for **post** request to `api/arms/set` endpoint\n- `head_move` for **post** request to `api/head` endpoint\n- `hazard_settings` for **post** request to `api/hazard/updatebasesettings` endpoint\n- `streaming_av_start` for **post** request to `api/avstreaming/start` endpoint\n- `streaming_av_stop` for **post** request to `api/avstreaming/stop` endpoint\n- `streaming_av_disable` for **post** request to `api/services/avstreaming/disable` endpoint\n- `streaming_av_enable` for **post** request to `api/services/avstreaming/enable` endpoint\n- `keyphrase_recognition_start` for **post** request to `api/audio/keyphrase/start` endpoint\n- `keyphrase_recognition_stop` for **post** request to `api/audio/keyphrase/stop` endpoint\n- `update_allow` for **post** request to `api/system/update/allow` endpoint\n- `update_perform` for **post** request to `api/system/update` endpoint\n- `update_perform_targeted` for **post** request to `api/system/update/component` endpoint\n- `update_prevent` for **post** request to `api/system/update/prevent` endpoint\n- `error_text_clear` for **post** request to `api/text/error/clear` endpoint\n- `camera_disable` for **post** request to `api/services/camera/disable` endpoint\n- `camera_enable` for **post** request to `api/services/camera/enable` endpoint\n- `restart` for **post** request to `api/reboot` endpoint\n- `volume_settings` for **post** request to `api/audio/volume` endpoint\n- `logs_settings` for **post** request to `api/logs/level` endpoint\n- `websocket_settings` for **post** request to `api/websocket/version` endpoint\n- `external_request` for **post** request to `api/request` endpoint\n</details>\n\n<details> \n    <summary>List of supported information keywords</summary>\n\n- `audio_file` for **get** request to `api/audio` endpoint\n- `audio_list` for **get** request to `api/audio/list` endpoint\n- `audio_status` for **get** request to `api/services/audio` endpoint\n- `image_file` for **get** request to `api/images` endpoint\n- `image_list` for **get** request to `api/images/list` endpoint\n- `video_file` for **get** request to `api/videos` endpoint\n- `video_list` for **get** request to `api/videos/list` endpoint\n- `av_status` for **get** request to `api/services/avstreaming` endpoint\n- `sensor_values` for **get** request to `api/serial` endpoint\n- `map_file` for **get** request to `api/slam/map` endpoint\n- `current_map_id` for **get** request to `api/slam/map/current` endpoint\n- `map_id_list` for **get** request to `api/slam/map/ids` endpoint\n- `slam_diagnostics` for **get** request to `api/slam/diagnostics` endpoint\n- `slam_path` for **get** request to `api/slam/path` endpoint\n- `slam_status` for **get** request to `api/slam/status` endpoint\n- `slam_enabled` for **get** request to `api/services/slam` endpoint\n- `picture_depth` for **get** request to `api/cameras/depth` endpoint\n- `picture_fisheye` for **get** request to `api/cameras/fisheye` endpoint\n- `picture_rgb` for **get** request to `api/cameras/rgb` endpoint\n- `faces_known` for **get** request to `api/faces` endpoint\n- `recording_file` for **get** request to `api/videos/recordings` endpoint\n- `recording_list` for **get** request to `api/videos/recordings/list` endpoint\n- `skills_running` for **get** request to `api/skills/running` endpoint\n- `skills_known` for **get** request to `api/skills` endpoint\n- `wifis_available` for **get** request to `api/networks/scan` endpoint\n- `wifis_saved` for **get** request to `api/networks` endpoint\n- `battery_status` for **get** request to `api/battery` endpoint\n- `camera_status` for **get** request to `api/services/camera` endpoint\n- `blink_settings` for **get** request to `api/blink/settings` endpoint\n- `hazards_settings` for **get** request to `api/hazards/settings` endpoint\n- `camera_settings` for **get** request to `api/camera` endpoint\n- `slam_visible_settings` for **get** request to `api/slam/settings/visible` endpoint\n- `slam_infrared_settings` for **get** request to `api/slam/settings/ir` endpoint\n- `update_settings` for **get** request to `api/system/update/settings` endpoint\n- `device` for **get** request to `api/device` endpoint\n- `help` for **get** request to `api/help` endpoint\n- `log` for **get** request to `api/logs` endpoint\n- `log_level` for **get** request to `api/logs/level` endpoint\n- `update_available` for **get** request to `api/system/updates` endpoint\n- `websockets` for **get** request to `api/websockets` endpoint\n- `websocket_version` for **get** request to `api/websocket/version`\n</details>\n\n<details> \n    <summary>List of supported data shortcuts</summary>\n\n- `led_off` for `{ "red": "0", "green": "0", "blue": "0" }`\n- `white_light` for `{ "red": "255", "green": "255", "blue": "255" }`\n- `red_light` for `{ "red": "255", "green": "0", "blue": "0" }`\n- `green_light` for `{ "red": "0", "green": "255", "blue": "0" }`\n- `blue_light` for `{ "red": "0", "green": "0", "blue": "255" }`\n- `yellow_light` for `{ "red": "255", "green": "255", "blue": "0" }`\n- `cyan_light` for `{ "red": "0", "green": "255", "blue": "255" }`\n- `magenta_light` for `{ "red": "255", "green": "0", "blue": "255" }`\n- `orange_light` for `{ "red": "255", "green": "125", "blue": "0" }`\n- `lime_light` for `{ "red": "125", "green": "255", "blue": "0" }`\n- `aqua_light` for `{ "red": "0", "green": "255", "blue": "125" }`\n- `azure_light` for `{ "red": "0", "green": "125", "blue": "255" }`\n- `violet_light` for `{ "red": "125", "green": "0", "blue": "255" }`\n- `pink_light` for `{ "red": "255", "green": "0", "blue": "125" }`\n- `low_volume` for `{ "Volume": "5" }`\n- `image_admiration` for `{"FileName": "e_Admiration.jpg"}`\n- `image_aggressiveness` for `{"FileName": "e_Aggressiveness.jpg"}`\n- `image_amazement` for `{"FileName": "e_Amazement.jpg"}`\n- `image_anger` for `{"FileName": "e_Anger.jpg"}`\n- `image_concerned` for `{"FileName": "e_ApprehensionConcerned.jpg"}`\n- `image_contempt` for `{"FileName": "e_Contempt.jpg"}`\n- `image_content_left` for `{"FileName": "e_ContentLeft.jpg"}`\n- `image_content_right` for `{"FileName": "e_ContentRight.jpg"}`\n- `image_content_default` for `{"FileName": "e_DefaultContent.jpg"}`\n- `image_disgust` for `{"FileName": "e_Disgust.jpg"}`\n- `image_disoriented` for `{"FileName": "e_Disoriented.jpg"}`\n- `image_hilarious` for `{"FileName": "e_EcstacyHilarious.jpg"}`\n- `image_starry_eyed` for `{"FileName": "e_EcstacyStarryEyed.jpg"}`\n- `image_fear` for `{"FileName": "e_Fear.jpg"}`\n- `image_grief` for `{"FileName": "e_Grief.jpg"}`\n- `image_joy_1` for `{"FileName": "e_Joy.jpg"}`\n- `image_joy_2` for `{"FileName": "e_Joy2.jpg"}`\n- `image_goofy_1` for `{"FileName": "e_JoyGoofy.jpg"}`\n- `image_goofy_2` for `{"FileName": "e_JoyGoofy2.jpg"}`\n- `image_goofy_3` for `{"FileName": "e_JoyGoofy3.jpg"}`\n- `image_love` for `{"FileName": "e_Love.jpg"}`\n- `image_rage_1` for `{"FileName": "e_Rage.jpg"}`\n- `image_rage_2` for `{"FileName": "e_Rage2.jpg"}`\n- `image_rage_3` for `{"FileName": "e_Rage3.jpg"}`\n- `image_rage_4` for `{"FileName": "e_Rage4.jpg"}`\n- `image_remorse` for `{"FileName": "e_RemorseShame.jpg"}`\n- `image_sadness` for `{"FileName": "e_Sadness.jpg"}`\n- `image_sleping_1` for `{"FileName": "e_Sleeping.jpg"}`\n- `image_sleeping_2` for `{"FileName": "e_SleepingZZZ.jpg"}`\n- `image_sleepy_1` for `{"FileName": "e_Sleepy.jpg"}`\n- `image_sleepy_2` for `{"FileName": "e_Sleepy2.jpg"}`\n- `image_sleepy_3` for `{"FileName": "e_Sleepy3.jpg"}`\n- `image_sleepy_4` for `{"FileName": "e_Sleepy4.jpg"}`\n- `image_surprise` for `{"FileName": "e_Surprise.jpg"}`\n- `image_system_black_screen` for `{"FileName": "e_SystemBlackScreen.jpg"}`\n- `image_system_blink_large` for `{"FileName": "e_SystemBlinkLarge.jpg"}`\n- `image_system_blink_standard` for `{"FileName": "e_SystemBlinkStandard.jpg"}`\n- `image_system_camera` for `{"FileName": "e_SystemCamera.jpg"}`\n- `image_system_flash` for `{"FileName": "e_SystemFlash.jpg"}`\n- `image_system_gear_prompt` for `{"FileName": "e_SystemGearPrompt.jpg"}`\n- `image_system_logo_prompt` for `{"FileName": "e_SystemLogoPrompt.jpg"}`\n- `image_terror_1` for `{"FileName": "e_Terror.jpg"}`\n- `image_terror_2` for `{"FileName": "e_Terror2.jpg"}`\n- `image_terror_left` for `{"FileName": "e_TerrorLeft.jpg"}`\n- `image_terror_right` for `{"FileName": "e_TerrorRight.jpg"}`\n- `sound_acceptance` for `{ "FileName": "s_Acceptance.wav" }`\n- `sound_amazement_1` for `{ "FileName": "s_Amazement.wav" }`\n- `sound_amazement_2` for `{ "FileName": "s_Amazement2.wav" }`\n- `sound_anger_1` for `{ "FileName": "s_Anger.wav" }`\n- `sound_anger_2` for `{ "FileName": "s_Anger2.wav" }`\n- `sound_anger_3` for `{ "FileName": "s_Anger3.wav" }`\n- `sound_anger_4` for `{ "FileName": "s_Anger4.wav" }`\n- `sound_annoyance_1` for `{ "FileName": "s_Annoyance.wav" }`\n- `sound_annoyance_2` for `{ "FileName": "s_Annoyance2.wav" }`\n- `sound_annoyance_3` for `{ "FileName": "s_Annoyance3.wav" }`\n- `sound_annoyance_4` for `{ "FileName": "s_Annoyance4.wav" }`\n- `sound_awe_1` for `{ "FileName": "s_Awe.wav" }`\n- `sound_awe_2` for `{ "FileName": "s_Awe2.wav" }`\n- `sound_awe_3` for `{ "FileName": "s_Awe3.wav" }`\n- `sound_boredom` for `{ "FileName": "s_Boredom.wav" }`\n- `sound_disapproval` for `{ "FileName": "s_Disapproval.wav" }`\n- `sound_disgust_1` for `{ "FileName": "s_Disgust.wav" }`\n- `sound_disgust_2` for `{ "FileName": "s_Disgust2.wav" }`\n- `sound_disgust_3` for `{ "FileName": "s_Disgust3.wav" }`\n- `sound_disoriented_1` for `{ "FileName": "s_DisorientedConfused.wav" }`\n- `sound_disoriented_2` for `{ "FileName": "s_DisorientedConfused2.wav" }`\n- `sound_disoriented_3` for `{ "FileName": "s_DisorientedConfused3.wav" }`\n- `sound_disoriented_4` for `{ "FileName": "s_DisorientedConfused4.wav" }`\n- `sound_disoriented_5` for `{ "FileName": "s_DisorientedConfused5.wav" }`\n- `sound_disoriented_6` for `{ "FileName": "s_DisorientedConfused6.wav" }`\n- `sound_distraction` for `{ "FileName": "s_Distraction.wav" }`\n- `sound_ecstacy_1` for `{ "FileName": "s_Ecstacy.wav" }`\n- `sound_ecstacy_2` for `{ "FileName": "s_Ecstacy2.wav" }`\n- `sound_fear` for `{ "FileName": "s_Fear.wav" }`\n- `sound_grief_1` for `{ "FileName": "s_Grief.wav" }`\n- `sound_grief_2` for `{ "FileName": "s_Grief2.wav" }`\n- `sound_grief_3` for `{ "FileName": "s_Grief3.wav" }`\n- `sound_grief_4` for `{ "FileName": "s_Grief4.wav" }`\n- `sound_joy_1` for `{ "FileName": "s_Joy.wav" }`\n- `sound_joy_2` for `{ "FileName": "s_Joy2.wav" }`\n- `sound_joy_3` for `{ "FileName": "s_Joy3.wav" }`\n- `sound_joy_4` for `{ "FileName": "s_Joy4.wav" }`\n- `sound_loathing` for `{ "FileName": "s_Loathing.wav" }`\n- `sound_love` for `{ "FileName": "s_Love.wav" }`\n- `sound_phrase_bye_bye` for `{ "FileName": "s_PhraseByeBye.wav" }`\n- `sound_phrase_evil` for `{ "FileName": "s_PhraseEvilAhHa.wav" }`\n- `sound_phrase_hello` for `{ "FileName": "s_PhraseHello.wav" }`\n- `sound_phrase_no` for `{ "FileName": "s_PhraseNoNoNo.wav" }`\n- `sound_phrase_oopsy` for `{ "FileName": "s_PhraseOopsy.wav" }`\n- `sound_phrase_ow` for `{ "FileName": "s_PhraseOwOwOw.wav" }`\n- `sound_phrase_oww` for `{ "FileName": "s_PhraseOwwww.wav" }`\n- `sound_phrase_uh` for `{ "FileName": "s_PhraseUhOh.wav" }`\n- `sound_rage` for `{ "FileName": "s_Rage.wav" }`\n- `sound_sadness_1` for `{ "FileName": "s_Sadness.wav" }`\n- `sound_sadness_2` for `{ "FileName": "s_Sadness2.wav" }`\n- `sound_sadness_3` for `{ "FileName": "s_Sadness3.wav" }`\n- `sound_sadness_4` for `{ "FileName": "s_Sadness4.wav" }`\n- `sound_sadness_5` for `{ "FileName": "s_Sadness5.wav" }`\n- `sound_sadness_6` for `{ "FileName": "s_Sadness6.wav" }`\n- `sound_sadness_7` for `{ "FileName": "s_Sadness7.wav" }`\n- `sound_sleepy_1` for `{ "FileName": "s_Sleepy.wav" }`\n- `sound_sleepy_2` for `{ "FileName": "s_Sleepy2.wav" }`\n- `sound_sleepy_3` for `{ "FileName": "s_Sleepy3.wav" }`\n- `sound_sleepy_4` for `{ "FileName": "s_Sleepy4.wav" }`\n- `sound_sleepy_snore` for `{ "FileName": "s_SleepySnore.wav" }`\n- `sound_camera_shutter` for `{ "FileName": "s_SystemCameraShutter.wav" }`\n- `sound_failure` for `{ "FileName": "s_SystemFailure.wav" }`\n- `sound_success` for `{ "FileName": "s_SystemSuccess.wav" }`\n- `sound_wake` for `{ "FileName": "s_SystemWakeWord.wav" }`\n</details>\n\n#### Adding custom keywords and shortcuts\n\nCustom keywords and shortcuts can be passed to a Misty object while declaring a new instance by using the optional arguments:\n\n- `custom_info` for custom information keywords (a dictionary with keys being the information keywords and values being the endpoints),\n- `custom_actions` for custom action keywords (a dictionary with keys being the action keywords and values being a dictionary `{"endpoint" : "edpoint_value", "method" : "method_value"}` where `method_value` is either `post` or `delete`),\n- `custom_data` for custom data shortcuts (a dictionary with keys being the data shortcuts and values being the dictionary of data values).\n\nAn example:\n\n```python\ncustom_allowed_infos = {\n    "hazards_settings": "api/hazards/settings"\n}\n\ncustom_allowed_data = {\n    "amazement": {\n        "FileName": "s_Amazement.wav"\n    },\n    "red": {\n        "red": "255",\n        "green": "0",\n        "blue": "0"\n    }\n}\n\ncustom_allowed_actions = {\n    "audio_play" : {\n        "endpoint" : "api/audio/play",\n        "method" : "post"\n    },\n    "delete_audio" : {\n        "endpoint" : "api/audio",\n        "method" : "delete"\n    }\n}\n\nmisty_robot = Misty("0.0.0.0", \n    custom_info=custom_allowed_infos, \n    custom_actions=custom_allowed_actions, \n    custom_data=custom_allowed_data)\n```\n\n## Running Misty2py from source\n\n- If this is your first time using `misty2py` from source, do following:\n\n  - Copy `.env.example` to `.env`.\n  - Replace the placeholder values in the new `.env` file.\n  - Run `poetry install` to obtain all dependencies.\n\n- Run the desired script via `poetry run python -m [name]` where `[name]` is the placeholder for the module location (in Python notation).\n- If the scripts run but your Misty does not seem to respond, you have most likely provided an incorrect IP address for `MISTY_IP_ADDRESS` in `.env`.\n\n## Pytests\n\nThis repository contains several parametrised unit tests under the pytest library that can be found in the directory `tests`. The test coverage is currently 84%.\n\n### Instructions for running the tests and test coverage reports\n\n- if this is your first time using misty2py from source, follow instructions in [Running Misty2py from source](#Running-Misty2py-from-source).\n  \n- Pytests can be run via `poetry run pytest .`.\n- The coverage report can be obtained via `poetry run pytest --cov-report html --cov=misty2py tests` for HTML output or via `poetry run pytest --cov=misty2py tests` for terminal output.\n',
    'author': "Chris 'Scar(R)ed' Vajdík",
    'author_email': 'scarred.chris@gmail.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://github.com/ChrisScarred/misty2py',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.9,<4.0',
}


setup(**setup_kwargs)
