Ejemplo n.º 1
0
def start_rhasspy() -> None:
    """Create actor system and Rhasspy core."""
    global core

    # Load core
    system = ActorSystem()
    core = RhasspyCore(args.profile,
                       system_profiles_dir,
                       user_profiles_dir,
                       actor_system=system)

    # Set environment variables
    os.environ["RHASSPY_BASE_DIR"] = os.getcwd()
    os.environ["RHASSPY_PROFILE"] = core.profile.name
    os.environ["RHASSPY_PROFILE_DIR"] = core.profile.write_dir()

    # Add profile settings from the command line
    extra_settings = {}
    for key, value in args.set:
        try:
            value = json.loads(value)
        except:
            pass

        logger.debug("Profile: {0}={1}".format(key, value))
        extra_settings[key] = value
        core.profile.set(key, value)

    # Load observer actor to catch intents
    observer = system.createActor(WebSocketObserver)
    system.ask(observer, ConfigureEvent(core.profile))

    core.start(observer=observer)
    logger.info("Started")
Ejemplo n.º 2
0
def start_rhasspy() -> None:
    global core

    default_settings = Profile.load_defaults(profiles_dirs)

    # Get name of profile
    profile_name = (
        args.profile
        or os.environ.get("RHASSPY_PROFILE", None)
        or pydash.get(default_settings, "rhasspy.default_profile", "en")
    )

    # Load core
    core = RhasspyCore(profile_name, profiles_dirs)

    # Set environment variables
    os.environ["RHASSPY_BASE_DIR"] = os.getcwd()
    os.environ["RHASSPY_PROFILE"] = core.profile.name
    os.environ["RHASSPY_PROFILE_DIR"] = core.profile.write_dir()

    # Add profile settings from the command line
    extra_settings = {}
    for key, value in args.set:
        try:
            value = json.loads(value)
        except:
            pass

        logger.debug("Profile: {0}={1}".format(key, value))
        extra_settings[key] = value
        core.profile.set(key, value)

    core.start()
    logger.info("Started")
Ejemplo n.º 3
0
    def test_training(self):
        """Test training"""
        profile_name = "en"
        with tempfile.TemporaryDirectory(prefix="rhasspy_") as temp_dir:
            profiles_dirs = [temp_dir, "profiles"]
            core = RhasspyCore(profile_name, profiles_dirs, do_logging=True)
            core.profile.set("rhasspy.listen_on_start", False)
            core.profile.set("rhasspy.preload_profile", False)
            core.start()

            sentences_path = core.profile.write_path(
                core.profile.get("speech_to_text.sentences_ini")
            )

            with open(sentences_path, "w") as sentences_file:
                print("[Foo]", file=sentences_file)
                print("foo bar", file=sentences_file)
                print("foo bar baz", file=sentences_file)

            core.train()
            with open("etc/test/what_time_is_it.wav", "rb") as wav_file:
                text = core.transcribe_wav(wav_file.read()).text
                assert text != "what time is it"

            # Add some more sentences
            with open(sentences_path, "a") as sentences_file:
                print("", file=sentences_file)
                print("[GetTime]", file=sentences_file)
                print("what time is it", file=sentences_file)

            core.train()
            with open("etc/test/what_time_is_it.wav", "rb") as wav_file:
                text = core.transcribe_wav(wav_file.read()).text
                assert text == "what time is it"
Ejemplo n.º 4
0
def start_rhasspy() -> None:
    global core

    default_settings = Profile.load_defaults(profiles_dirs)

    # Get name of profile
    profile_name = args.profile \
        or os.environ.get('RHASSPY_PROFILE', None) \
        or pydash.get(default_settings, 'rhasspy.default_profile', 'en')

    # Load core
    core = RhasspyCore(profile_name, profiles_dirs)

    # Set environment variables
    os.environ['RHASSPY_BASE_DIR'] = os.getcwd()
    os.environ['RHASSPY_PROFILE'] = core.profile.name
    os.environ['RHASSPY_PROFILE_DIR'] = core.profile.write_dir()

    # Add profile settings from the command line
    extra_settings = {}
    for key, value in args.set:
        try:
            value = json.loads(value)
        except:
            pass

        logger.debug('Profile: {0}={1}'.format(key, value))
        extra_settings[key] = value
        core.profile.set(key, value)

    core.start()
Ejemplo n.º 5
0
    def __enter__(self):
        self.user_profiles_dir = tempfile.TemporaryDirectory()
        self.core = RhasspyCore(self.profile_name, self.system_profiles_dir,
                                self.user_profiles_dir.name)
        self.core.profile.set("wake.system", "dummy")
        self.core.start(preload=False)

        if self.train:
            self.core.train()

        return self.core
Ejemplo n.º 6
0
def _send_frame(
    core: RhasspyCore,
    topic: str,
    audio_data: bytes,
    rate: int,
    width: int,
    channels: int,
) -> None:
    with io.BytesIO() as mqtt_buffer:
        with wave.open(mqtt_buffer, mode="wb") as mqtt_file:
            mqtt_file.setframerate(rate)
            mqtt_file.setsampwidth(width)
            mqtt_file.setnchannels(channels)
            mqtt_file.writeframesraw(audio_data)

        # Send audio frame WAV
        mqtt_payload = mqtt_buffer.getvalue()
        core.mqtt_publish(topic, mqtt_payload)
Ejemplo n.º 7
0
class RhasspyTestCore:
    def __init__(self, profile_name, train=True):
        self.profile_name = profile_name
        self.system_profiles_dir = os.path.join(os.getcwd(), "profiles")
        self.train = train

    def __enter__(self):
        self.user_profiles_dir = tempfile.TemporaryDirectory()
        self.core = RhasspyCore(self.profile_name, self.system_profiles_dir,
                                self.user_profiles_dir.name)
        self.core.profile.set("wake.system", "dummy")
        self.core.start(preload=False)

        if self.train:
            self.core.train()

        return self.core

    def __exit__(self, *args):
        self.core.shutdown()

        try:
            self.user_profiles_dir.cleanup()
        except:
            pass
Ejemplo n.º 8
0
async def main() -> None:
    global mic_stdin_running, mic_stdin_thread

    # Parse command-line arguments
    parser = argparse.ArgumentParser(description="Rhasspy")
    parser.add_argument("--profile",
                        "-p",
                        required=True,
                        type=str,
                        help="Name of profile to use")
    parser.add_argument(
        "--system-profiles",
        type=str,
        help="Directory with base profile files (read only)",
        default=os.path.join(os.getcwd(), "profiles"),
    )
    parser.add_argument(
        "--user-profiles",
        type=str,
        help="Directory with user profile files (read/write)",
        default=os.path.expanduser("~/.config/rhasspy/profiles"),
    )
    parser.add_argument(
        "--set",
        "-s",
        nargs=2,
        action="append",
        help="Set a profile setting value",
        default=[],
    )
    parser.add_argument("--debug",
                        action="store_true",
                        help="Print DEBUG log to console")
    parser.add_argument(
        "--no-check",
        action="store_true",
        help="Don't check profile for necessary files",
    )

    sub_parsers = parser.add_subparsers(dest="command")
    sub_parsers.required = True

    # info
    info_parser = sub_parsers.add_parser("info", help="Profile information")
    info_parser.add_argument("--defaults",
                             action="store_true",
                             help="Only print default settings")

    sentences_parser = sub_parsers.add_parser(
        "sentences", help="Print profile sentences.ini")

    # validate
    # validate_parser = sub_parsers.add_parser(
    #     "validate", help="Validate profile against schema"
    # )

    # wav2text
    wav2text_parser = sub_parsers.add_parser(
        "wav2text", help="WAV file to text transcription")
    wav2text_parser.add_argument("wav_files",
                                 nargs="*",
                                 help="Paths to WAV files")

    # text2intent
    text2intent_parser = sub_parsers.add_parser("text2intent",
                                                help="Text parsed to intent")
    text2intent_parser.add_argument("sentences",
                                    nargs="*",
                                    help="Sentences to parse")
    text2intent_parser.add_argument("--handle",
                                    action="store_true",
                                    help="Pass result to intent handler")

    # wav2intent
    wav2intent_parser = sub_parsers.add_parser(
        "wav2intent", help="WAV file to parsed intent")
    wav2intent_parser.add_argument("wav_files",
                                   nargs="*",
                                   help="Paths to WAV files")
    wav2intent_parser.add_argument("--handle",
                                   action="store_true",
                                   help="Pass result to intent handler")

    # train
    train_parser = sub_parsers.add_parser("train", help="Re-train profile")

    # record
    # record_parser = sub_parsers.add_parser('record', help='Record test phrases for profile')
    # record_parser.add_argument('--directory', help='Directory to write WAV files and intent JSON files')

    # record-wake
    # record_wake_parser = sub_parsers.add_parser('record-wake', help='Record wake word examples for profile')
    # record_wake_parser.add_argument('--directory', help='Directory to write WAV files')
    # record_wake_parser.add_argument('--negative', action='store_true', help='Record negative examples (not the wake word)')

    # tune
    # tune_parser = sub_parsers.add_parser('tune', help='Tune speech acoustic model for profile')
    # tune_parser.add_argument('--directory', help='Directory with WAV files and intent JSON files')

    # tune-wake
    # tune_wake_parser = sub_parsers.add_parser('tune-wake', help='Tune wake acoustic model for profile')
    # tune_wake_parser.add_argument('--directory', help='Directory with WAV files')

    # test
    # test_parser = sub_parsers.add_parser('test', help='Test speech/intent recognizers for profile')
    # test_parser.add_argument('directory', help='Directory with WAV files and intent JSON files')

    # test-wake
    # test_wake_parser = sub_parsers.add_parser(
    #     "test-wake", help="Test wake word examples for profile"
    # )
    # test_wake_parser.add_argument("directory", help="Directory with WAV files")
    # test_wake_parser.add_argument(
    #     "--threads", type=int, default=4, help="Number of threads to use"
    # )
    # test_wake_parser.add_argument(
    #     "--system", type=str, default=None, help="Override wake word system"
    # )

    # mic2wav
    mic2wav_parser = sub_parsers.add_parser("mic2wav",
                                            help="Voice command to WAV data")
    mic2wav_parser.add_argument(
        "--timeout",
        type=float,
        default=None,
        help="Maximum number of seconds to record (default=profile)",
    )

    # mic2text
    mic2text_parser = sub_parsers.add_parser(
        "mic2text", help="Voice command to text transcription")
    mic2text_parser.add_argument(
        "--timeout",
        type=float,
        default=None,
        help="Maximum number of seconds to record (default=profile)",
    )

    # mic2intent
    mic2intent_parser = sub_parsers.add_parser(
        "mic2intent", help="Voice command to parsed intent")
    mic2intent_parser.add_argument("--stdin",
                                   action="store_true",
                                   help="Read audio data from stdin")
    mic2intent_parser.add_argument("--handle",
                                   action="store_true",
                                   help="Pass result to intent handler")
    mic2intent_parser.add_argument(
        "--timeout",
        type=float,
        default=None,
        help="Maximum number of seconds to record (default=profile)",
    )

    # word2phonemes
    word2phonemes_parser = sub_parsers.add_parser(
        "word2phonemes", help="Get pronunciation(s) for word(s)")
    word2phonemes_parser.add_argument("words",
                                      nargs="*",
                                      help="Word(s) to pronounce")
    word2phonemes_parser.add_argument("-n",
                                      type=int,
                                      default=1,
                                      help="Maximum number of pronunciations")

    # word2wav
    word2wav_parser = sub_parsers.add_parser("word2wav", help="Pronounce word")
    word2wav_parser.add_argument("word", help="Word to pronounce")

    # wav2mqtt
    wav2mqtt_parser = sub_parsers.add_parser("wav2mqtt",
                                             help="Push WAV file(s) to MQTT")
    wav2mqtt_parser.add_argument("wav_files",
                                 nargs="*",
                                 help="Paths to WAV files")
    wav2mqtt_parser.add_argument(
        "--frames",
        type=int,
        default=480,
        help="WAV frames per MQTT message (default=0 for all)",
    )
    wav2mqtt_parser.add_argument("--site-id",
                                 type=str,
                                 default="default",
                                 help="Hermes siteId (default=default)")
    wav2mqtt_parser.add_argument(
        "--silence-before",
        type=float,
        default=0,
        help="Seconds of silence to add before each WAV",
    )
    wav2mqtt_parser.add_argument(
        "--silence-after",
        type=float,
        default=0,
        help="Seconds of silence to add after each WAV",
    )
    wav2mqtt_parser.add_argument(
        "--pause",
        type=float,
        default=0.01,
        help="Seconds to wait before sending next chunk (default=0.01)",
    )

    # text2wav
    text2wav_parser = sub_parsers.add_parser(
        "text2wav", help="Output WAV file using text to speech system")
    text2wav_parser.add_argument("sentence", help="Sentence to speak")

    # text2speech
    text2speech_parser = sub_parsers.add_parser(
        "text2speech", help="Speak sentences using text to speech system")
    text2speech_parser.add_argument("sentences",
                                    nargs="*",
                                    help="Sentences to speak")

    # sleep
    sleep_parser = sub_parsers.add_parser("sleep", help="Wait for wake word")

    # download
    download_parser = sub_parsers.add_parser("download",
                                             help="Download profile files")
    download_parser.add_argument(
        "--delete",
        action="store_true",
        help="Clear download cache before downloading")

    # check
    check_parser = sub_parsers.add_parser(
        "check", help="Check downloaded profile files")

    # -------------------------------------------------------------------------

    args = parser.parse_args()

    if args.debug:
        logging.root.setLevel(logging.DEBUG)

    profiles_dirs = [args.system_profiles, args.user_profiles]
    logger.debug(profiles_dirs)

    default_settings = Profile.load_defaults(args.system_profiles)

    # Create rhasspy core
    from rhasspy.core import RhasspyCore

    core = RhasspyCore(args.profile, args.system_profiles, args.user_profiles)

    # Add profile settings from the command line
    extra_settings = {}
    for key, value in args.set:
        try:
            value = json.loads(value)
        except:
            pass

        logger.debug("Profile: {0}={1}".format(key, value))
        extra_settings[key] = value
        core.profile.set(key, value)

    # Handle command
    if args.command == "info":
        if args.defaults:
            # Print default settings
            json.dump(core.defaults, sys.stdout, indent=4)
        else:
            # Print profile settings
            json.dump(core.profile.json, sys.stdout, indent=4)
    # elif args.command == "validate":
    #     from cerberus import Validator

    #     schema_path = os.path.join(os.path.dirname(__file__), "profile_schema.json")
    #     with open(schema_path, "r") as schema_file:
    #         v = Validator(json.load(schema_file))
    #         if v.validate(core.profile.json):
    #             print("VALID")
    #         else:
    #             print("INVALID")
    #             for err in v._errors:
    #                 print(err)
    elif args.command == "sentences":
        sentences_path = core.profile.read_path(
            core.profile.get("speech_to_text.sentences_ini", "sentences.ini"))

        with open(sentences_path, "r") as sentences_file:
            sys.stdout.write(sentences_file.read())
    else:
        # Patch profile
        profile = core.profile
        profile.set("rhasspy.listen_on_start", False)
        profile.set("rhasspy.preload_profile", False)

        if args.command == "wav2mqtt":
            profile.set("mqtt.enabled", True)
        elif args.command in ["mic2intent"] and args.stdin:
            profile.set("microphone.system", "stdin")
            profile.set("microphone.stdin.auto_start", False)
            mic_stdin_running = True
        elif args.command == "text2wav":
            profile.set("sounds.system", "dummy")

        # Set environment variables
        os.environ["RHASSPY_BASE_DIR"] = os.getcwd()
        os.environ["RHASSPY_PROFILE"] = core.profile.name
        os.environ["RHASSPY_PROFILE_DIR"] = core.profile.write_dir()

        # Execute command
        command_funcs = {
            "wav2text": wav2text,
            "text2intent": text2intent,
            "wav2intent": wav2intent,
            "train": train_profile,
            # 'record': record,
            # 'record-wake': record_wake,
            # 'tune': tune,
            # 'tune-wake': tune_wake,
            # 'test': test,
            # "test-wake": test_wake,
            "mic2text": mic2text,
            "mic2intent": mic2intent,
            "mic2wav": mic2wav,
            "word2phonemes": word2phonemes,
            "word2wav": word2wav,
            "wav2mqtt": wav2mqtt,
            "text2wav": text2wav,
            "text2speech": text2speech,
            "sleep": sleep,
            "download": download,
            "check": check,
        }

        if not args.command in ["test-wake"]:
            # Automatically start core
            await core.start()

        if not args.no_check and (args.command not in ["check", "download"]):
            # Verify that profile has necessary files
            missing_files = core.check_profile()
            if len(missing_files) > 0:
                logger.fatal(
                    f"Missing required files for {profile.name}: {missing_files.keys()}. Please run download command and try again."
                )
                sys.exit(1)

        if mic_stdin_running:
            logger.debug("Reading audio data from stdin")
            mic_stdin_thread = threading.Thread(target=read_audio_stdin,
                                                args=(core, ),
                                                daemon=True)
            mic_stdin_thread.start()

        # Run command
        try:
            await command_funcs[args.command](core, profile, args)

            if mic_stdin_thread is not None:
                mic_stdin_running = False
                mic_stdin_thread.join()
        finally:
            await core.shutdown()
Ejemplo n.º 9
0
async def check(core: RhasspyCore, profile: Profile, args: Any) -> None:
    missing_files = core.check_profile()
    json.dump(missing_files, sys.stdout, indent=4)
Ejemplo n.º 10
0
def read_audio_stdin(core: RhasspyCore, chunk_size: int = 960):
    global mic_stdin_running
    while mic_stdin_running:
        audio_data = sys.stdin.buffer.read(chunk_size)
        core.send_audio_data(AudioData(audio_data))
Ejemplo n.º 11
0
async def check(core: RhasspyCore, profile: Profile, args: Any) -> None:
    """Verify that profile files are downloaded"""
    missing_files = core.check_profile()
    json.dump(missing_files, sys.stdout, indent=4)
Ejemplo n.º 12
0
async def main() -> None:
    """Main method"""
    global mic_stdin_running, mic_stdin_thread

    # Parse command-line arguments
    parser = argparse.ArgumentParser(description="Rhasspy")
    parser.add_argument("--profile",
                        "-p",
                        required=True,
                        type=str,
                        help="Name of profile to use")
    parser.add_argument(
        "--system-profiles",
        type=str,
        help="Directory with base profile files (read only)",
        default=os.path.join(os.getcwd(), "profiles"),
    )
    parser.add_argument(
        "--user-profiles",
        type=str,
        help="Directory with user profile files (read/write)",
        default=os.path.expanduser("~/.config/rhasspy/profiles"),
    )
    parser.add_argument(
        "--set",
        "-s",
        nargs=2,
        action="append",
        help="Set a profile setting value",
        default=[],
    )
    parser.add_argument("--debug",
                        action="store_true",
                        help="Print DEBUG log to console")
    parser.add_argument(
        "--no-check",
        action="store_true",
        help="Don't check profile for necessary files",
    )

    sub_parsers = parser.add_subparsers(dest="command")
    sub_parsers.required = True

    # info
    info_parser = sub_parsers.add_parser("info", help="Profile information")
    info_parser.add_argument("--defaults",
                             action="store_true",
                             help="Only print default settings")

    # wav2text
    wav2text_parser = sub_parsers.add_parser(
        "wav2text", help="WAV file to text transcription")
    wav2text_parser.add_argument("wav_files",
                                 nargs="*",
                                 help="Paths to WAV files")

    # text2intent
    text2intent_parser = sub_parsers.add_parser("text2intent",
                                                help="Text parsed to intent")
    text2intent_parser.add_argument("sentences",
                                    nargs="*",
                                    help="Sentences to parse")
    text2intent_parser.add_argument("--handle",
                                    action="store_true",
                                    help="Pass result to intent handler")

    # wav2intent
    wav2intent_parser = sub_parsers.add_parser(
        "wav2intent", help="WAV file to parsed intent")
    wav2intent_parser.add_argument("wav_files",
                                   nargs="*",
                                   help="Paths to WAV files")
    wav2intent_parser.add_argument("--handle",
                                   action="store_true",
                                   help="Pass result to intent handler")

    # train
    train_parser = sub_parsers.add_parser("train", help="Re-train profile")
    train_parser.add_argument("--no-cache",
                              action="store_true",
                              help="Clear training cache")

    # mic2wav
    mic2wav_parser = sub_parsers.add_parser("mic2wav",
                                            help="Voice command to WAV data")
    mic2wav_parser.add_argument(
        "--timeout",
        type=float,
        default=None,
        help="Maximum number of seconds to record (default=profile)",
    )

    # mic2text
    mic2text_parser = sub_parsers.add_parser(
        "mic2text", help="Voice command to text transcription")
    mic2text_parser.add_argument(
        "--timeout",
        type=float,
        default=None,
        help="Maximum number of seconds to record (default=profile)",
    )

    # mic2intent
    mic2intent_parser = sub_parsers.add_parser(
        "mic2intent", help="Voice command to parsed intent")
    mic2intent_parser.add_argument("--stdin",
                                   action="store_true",
                                   help="Read audio data from stdin")
    mic2intent_parser.add_argument("--handle",
                                   action="store_true",
                                   help="Pass result to intent handler")
    mic2intent_parser.add_argument(
        "--timeout",
        type=float,
        default=None,
        help="Maximum number of seconds to record (default=profile)",
    )

    # word2phonemes
    word2phonemes_parser = sub_parsers.add_parser(
        "word2phonemes", help="Get pronunciation(s) for word(s)")
    word2phonemes_parser.add_argument("words",
                                      nargs="*",
                                      help="Word(s) to pronounce")
    word2phonemes_parser.add_argument("-n",
                                      type=int,
                                      default=1,
                                      help="Maximum number of pronunciations")

    # word2wav
    word2wav_parser = sub_parsers.add_parser("word2wav", help="Pronounce word")
    word2wav_parser.add_argument("word", help="Word to pronounce")

    # wav2mqtt
    wav2mqtt_parser = sub_parsers.add_parser("wav2mqtt",
                                             help="Push WAV file(s) to MQTT")
    wav2mqtt_parser.add_argument("wav_files",
                                 nargs="*",
                                 help="Paths to WAV files")
    wav2mqtt_parser.add_argument(
        "--frames",
        type=int,
        default=480,
        help="WAV frames per MQTT message (default=0 for all)",
    )
    wav2mqtt_parser.add_argument("--site-id",
                                 type=str,
                                 default="default",
                                 help="Hermes siteId (default=default)")
    wav2mqtt_parser.add_argument(
        "--silence-before",
        type=float,
        default=0,
        help="Seconds of silence to add before each WAV",
    )
    wav2mqtt_parser.add_argument(
        "--silence-after",
        type=float,
        default=0,
        help="Seconds of silence to add after each WAV",
    )
    wav2mqtt_parser.add_argument(
        "--pause",
        type=float,
        default=0.01,
        help="Seconds to wait before sending next chunk (default=0.01)",
    )

    # text2wav
    text2wav_parser = sub_parsers.add_parser(
        "text2wav", help="Output WAV file using text to speech system")
    text2wav_parser.add_argument("sentence", help="Sentence to speak")

    # text2speech
    text2speech_parser = sub_parsers.add_parser(
        "text2speech", help="Speak sentences using text to speech system")
    text2speech_parser.add_argument("sentences",
                                    nargs="*",
                                    help="Sentences to speak")

    # sleep
    sub_parsers.add_parser("sleep", help="Wait for wake word")

    # download
    download_parser = sub_parsers.add_parser("download",
                                             help="Download profile files")
    download_parser.add_argument(
        "--delete",
        action="store_true",
        help="Clear download cache before downloading")

    # check
    sub_parsers.add_parser("check", help="Check downloaded profile files")

    # -------------------------------------------------------------------------

    args = parser.parse_args()

    if args.debug:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    profiles_dirs = [args.system_profiles, args.user_profiles]
    logger.debug(profiles_dirs)

    # Create rhasspy core
    core = RhasspyCore(args.profile, args.system_profiles, args.user_profiles)

    # Add profile settings from the command line
    extra_settings = {}
    for key, value in args.set:
        try:
            value = json.loads(value)
        except Exception:
            pass

        logger.debug("Profile: %s=%s", key, value)
        extra_settings[key] = value
        core.profile.set(key, value)

    # Handle command
    if args.command == "info":
        if args.defaults:
            # Print default settings
            json.dump(core.defaults, sys.stdout, indent=4)
        else:
            # Print profile settings
            json.dump(core.profile.json, sys.stdout, indent=4)
    elif args.command == "sentences":
        sentences_path = core.profile.read_path(
            core.profile.get("speech_to_text.sentences_ini", "sentences.ini"))

        with open(sentences_path, "r") as sentences_file:
            sys.stdout.write(sentences_file.read())
    else:
        # Patch profile
        profile = core.profile
        profile.set("rhasspy.listen_on_start", False)
        profile.set("rhasspy.preload_profile", False)

        if args.command == "wav2mqtt":
            profile.set("mqtt.enabled", True)
        elif args.command in ["mic2intent"] and args.stdin:
            profile.set("microphone.system", "stdin")
            profile.set("microphone.stdin.auto_start", False)
            mic_stdin_running = True
        elif args.command == "text2wav":
            profile.set("sounds.system", "dummy")

        # Set environment variables
        os.environ["RHASSPY_BASE_DIR"] = os.getcwd()
        os.environ["RHASSPY_PROFILE"] = core.profile.name
        os.environ["RHASSPY_PROFILE_DIR"] = core.profile.write_dir()

        # Execute command
        command_funcs = {
            "wav2text": wav2text,
            "text2intent": text2intent,
            "wav2intent": wav2intent,
            "train": train_profile,
            "mic2text": mic2text,
            "mic2intent": mic2intent,
            "mic2wav": mic2wav,
            "word2phonemes": word2phonemes,
            "word2wav": word2wav,
            "wav2mqtt": wav2mqtt,
            "text2wav": text2wav,
            "text2speech": text2speech,
            "sleep": sleep,
            "download": download,
            "check": check,
        }

        # Automatically start core
        await core.start()

        if not args.no_check and (args.command not in ["check", "download"]):
            # Verify that profile has necessary files
            missing_files = core.check_profile()
            if missing_files:
                logger.fatal(
                    "Missing required files for %s: %s. Please run download command and try again.",
                    profile.name,
                    list(missing_files),
                )
                sys.exit(1)

        if mic_stdin_running:
            logger.debug("Reading audio data from stdin")
            mic_stdin_thread = threading.Thread(target=read_audio_stdin,
                                                args=(core, ),
                                                daemon=True)
            mic_stdin_thread.start()

        # Run command
        try:
            await command_funcs[args.command](core, profile, args)

            if mic_stdin_thread is not None:
                mic_stdin_running = False
                mic_stdin_thread.join()
        finally:
            await core.shutdown()
Ejemplo n.º 13
0
class RhasspyTestCase(unittest.TestCase):
    def setUp(self):
        profile_name = "en"
        profiles_dirs = ["profiles"]
        self.core = RhasspyCore(profile_name, profiles_dirs, do_logging=False)
        self.core.profile.set("wake.system", "dummy")
        self.core.start()

    def tearDown(self):
        self.core.shutdown()

    # -------------------------------------------------------------------------

    def test_transcribe(self):
        """speech -> text"""
        with open("etc/test/turn_on_living_room_lamp.wav", "rb") as wav_file:
            text = self.core.transcribe_wav(wav_file.read()).text
            assert text == "turn on the living room lamp"

    # -------------------------------------------------------------------------

    def test_recognize(self):
        """text -> intent"""
        intent = self.core.recognize_intent("turn on the living room lamp").intent
        assert intent["intent"]["name"] == "ChangeLightState"
        entities = {e["entity"]: e["value"] for e in intent["entities"]}
        assert entities["name"] == "living room lamp"
        assert entities["state"] == "on"

    # -------------------------------------------------------------------------

    def test_training(self):
        """Test training"""
        profile_name = "en"
        with tempfile.TemporaryDirectory(prefix="rhasspy_") as temp_dir:
            profiles_dirs = [temp_dir, "profiles"]
            core = RhasspyCore(profile_name, profiles_dirs, do_logging=True)
            core.profile.set("rhasspy.listen_on_start", False)
            core.profile.set("rhasspy.preload_profile", False)
            core.start()

            sentences_path = core.profile.write_path(
                core.profile.get("speech_to_text.sentences_ini")
            )

            with open(sentences_path, "w") as sentences_file:
                print("[Foo]", file=sentences_file)
                print("foo bar", file=sentences_file)
                print("foo bar baz", file=sentences_file)

            core.train()
            with open("etc/test/what_time_is_it.wav", "rb") as wav_file:
                text = core.transcribe_wav(wav_file.read()).text
                assert text != "what time is it"

            # Add some more sentences
            with open(sentences_path, "a") as sentences_file:
                print("", file=sentences_file)
                print("[GetTime]", file=sentences_file)
                print("what time is it", file=sentences_file)

            core.train()
            with open("etc/test/what_time_is_it.wav", "rb") as wav_file:
                text = core.transcribe_wav(wav_file.read()).text
                assert text == "what time is it"

    # -------------------------------------------------------------------------

    def test_pronounce(self):
        # Known word
        pronunciations = self.core.get_word_pronunciations(["test"], n=1).pronunciations
        assert pronunciations["test"]["pronunciations"][0] == "T EH S T"

        # Unknown word
        pronunciations = self.core.get_word_pronunciations(
            ["raxacoricofallipatorius"], n=1
        ).pronunciations
        assert (
            "R AE K S AH K AO R IH K AO F AE L AH P AH T AO R IY IH S"
            in pronunciations["raxacoricofallipatorius"]["pronunciations"]
        )
Ejemplo n.º 14
0
 def setUp(self):
     profile_name = "en"
     profiles_dirs = ["profiles"]
     self.core = RhasspyCore(profile_name, profiles_dirs, do_logging=False)
     self.core.profile.set("wake.system", "dummy")
     self.core.start()