diff --git a/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/DialogProcessor.java b/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/DialogProcessor.java index d721ffc722..0d72ad899d 100644 --- a/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/DialogProcessor.java +++ b/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/DialogProcessor.java @@ -121,7 +121,7 @@ public class DialogProcessor implements KSListener, STTListener { this.bundle = bundle; this.ksFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), ks.getSupportedFormats()); this.sttFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), stt.getSupportedFormats()); - this.ttsFormat = VoiceManagerImpl.getBestMatch(sink.getSupportedFormats(), tts.getSupportedFormats()); + this.ttsFormat = VoiceManagerImpl.getBestMatch(tts.getSupportedFormats(), sink.getSupportedFormats()); } public void start() { diff --git a/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/VoiceManagerImpl.java b/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/VoiceManagerImpl.java index cbf3284e85..64c16a1f42 100644 --- a/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/VoiceManagerImpl.java +++ b/bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/VoiceManagerImpl.java @@ -225,19 +225,19 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider { throw new TTSException( "Unable to find a voice for language " + localeProvider.getLocale().getLanguage()); } - Set sttAudioFormats = tts.getSupportedFormats(); + Set ttsSupportedFormats = tts.getSupportedFormats(); AudioSink sink = audioManager.getSink(sinkId); if (sink == null) { throw new TTSException("Unable to find the audio sink " + sinkId); } - AudioFormat sttAudioFormat = getBestMatch(sink.getSupportedFormats(), sttAudioFormats); - if (sttAudioFormat == null) { + AudioFormat ttsAudioFormat = getBestMatch(ttsSupportedFormats, sink.getSupportedFormats()); + if (ttsAudioFormat == null) { throw new TTSException("No compatible audio format found for TTS '" + tts.getId() + "' and sink '" + sink.getId() + "'"); } - AudioStream audioStream = tts.synthesize(text, voice, sttAudioFormat); + AudioStream audioStream = tts.synthesize(text, voice, ttsAudioFormat); if (!sink.getSupportedStreams().stream().anyMatch(clazz -> clazz.isInstance(audioStream))) { throw new TTSException( "Failed playing audio stream '" + audioStream + "' as audio sink doesn't support it"); @@ -503,8 +503,9 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider { if (ksService == null || sttService == null || ttsService == null || interpreter == null || audioSource == null || audioSink == null || b == null) { throw new IllegalStateException("Cannot start dialog as services are missing."); - } else if (!ksService.getSupportedLocales().contains(loc) || !sttService.getSupportedLocales().contains(loc) - || !interpreter.getSupportedLocales().contains(loc)) { + } else if (!checkLocales(ksService.getSupportedLocales(), loc) + || !checkLocales(sttService.getSupportedLocales(), loc) + || !checkLocales(interpreter.getSupportedLocales(), loc)) { throw new IllegalStateException("Cannot start dialog as provided locale is not supported by all services."); } else { DialogProcessor processor = dialogProcessors.get(audioSource.getId()); @@ -548,6 +549,18 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider { dialogProcessors.clear(); } + private boolean checkLocales(@Nullable Set supportedLocales, Locale locale) { + if (supportedLocales == null) { + // rule interpreter returns null so allowing it + return true; + } + return supportedLocales.stream().anyMatch(sLocale -> { + var country = sLocale.getCountry(); + return Objects.equals(sLocale.getLanguage(), locale.getLanguage()) + && (country == null || country.isBlank() || country.equals(locale.getCountry())); + }); + } + @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC) protected void addKSService(KSService ksService) { this.ksServices.put(ksService.getId(), ksService);