Google TTS. Missing service configuration

Hi everyone!

The binding worked fine, and one month before, probably after some upgrade, I got this error. I tried everything: made new credentials, reinstalled binding, restarted openHab, reboot, etc… After every those moves it working some time and after a while I getting same error:


[WARN ] [core.voice.internal.VoiceManagerImpl] - Error saying 'Good morning': Missing service configuration.

Have somebody any idea which way I should dig?

I not using the Google TTS any more, but I think I was facing this issue last time:

A Google Cloud Platform project with an OAuth consent screen configured for an external user type and a publishing status of "Testing" is issued a refresh token expiring in 7 days.

I found that in this thread Do Google refresh tokens expire? - Stack Overflow and as the service fail seems to happen weekly I assumed it was that.

At the end I just moved to VoiceRSS, so I don’t have a solution sorry.

This happens a few hours after OpenHab is restarted. I restart OpenHab, then the “say” command works for ~a couple of hours and then I’m getting this error. So I don’t think this is a problem on Google’s side.

Maybe there is an error indeed, if you look at the addon code inside the synthesizeSpeech method the exceptions AuthenticationException and CommunicationException are handled in the same way, so any of them will toggle the variable initialized to false which causes the service to return that error. I don’t know enough about the addon but that seems like a possible root cause.

Then I would get an warning: “Error initializing Google Cloud TTS service: {}” but I don’t receive it. I’m getting only “Missing service configuration”. I found this warning in GoogleTTSService.java on line 305, because oAuthService becomes to null.

Seems that I looked by error on my fork which is outdated, sorry. Yes the same seems to remain, I was meaning this catch that handles both AuthenticationException and CommunicationException. I see a little weird than the oAuthService has to be disposed in both cases, but maybe there is an explanation for it. (file GoogleCloudAPI.java)

  public byte[] synthesizeSpeech(String text, GoogleTTSVoice voice, String codec) {
        ...
        try {
            ...
        } catch (AuthenticationException | CommunicationException e) {
            logger.warn("Error initializing Google Cloud TTS service: {}", e.getMessage());
            if (oAuthService != null) {
                oAuthFactory.ungetOAuthService(GoogleTTSService.SERVICE_PID);
                oAuthService = null;
            }
            ...
        }
        ...
    }

Edit:

Sorry I miss read the message, yes you will have the warning them.

My only other guess is that it can be happening inside the setConfig method because the service implementation is calling it in the wrong moment. If you can add some debug log there maybe you can catch it.

Edit 2:
I think I found the error it is on the updateConfig method of the service class:

 if (config.clientId != null && !config.clientId.isEmpty() && config.clientSecret != null && !config.clientSecret.isEmpty()) {
                apiImpl.setConfig(config);
                if (apiImpl.isInitialized()) {
                    allVoices = initVoices();
                    audioFormats = initAudioFormats();
                }
}

That if block only should be executed if the config authCode is not empty, but it was forgotten.

So when you reset the addon the activate method will pass the correct oAuthFactory to the apiImpl but the call to updateConfig will clean it up.

    @Activate
    protected void activate(Map<String, Object> config) {
        apiImpl = new GoogleCloudAPI(configAdmin, oAuthFactory);
        updateConfig(config);
    }

Thanks @Miguel_M.A.D for help. I don’t know if they change something, but after upgrade openHab (12 hours ago) to 4.0.3, I’m not getting that warning anymore. It may be too early to rejoice, but so far everything is working longer than before.

1 Like

It was too early to rejoice. And now i caught this warning:

Error initializing Google Cloud TTS service: An unexpected IOException occurred: java.util.concurrent.TimeoutException: Total timeout 5000 ms elapsed. 

So it means that you was right in the beginning, I just haven’t seen this warning before. Here is a reason:

catch (AuthenticationException | CommunicationException e) {
            logger.warn("Error initializing Google Cloud TTS service: {}", e.getMessage());
            if (oAuthService != null) {
                oAuthFactory.ungetOAuthService(GoogleTTSService.SERVICE_PID);
                oAuthService = null;
            }

Oh, good to now. I realize my second guess was wrong after reviewing the code again, so I didn’t know what else could be.

Probably a PR that checks the error cause and discard timeout errors could fix the problem.
Also, is that timeout configurable? For me seems a good idea to make it configurable if not.

No, this is not configurable. I think the problem is that I’m using TTS with ChatGPT. And ChatGPT sometimes returns a strange response with hieroglyphs, probably because I use Cyrillic. But anyway timeoutException shouldn’t reset oAuthService. This is a wrong behavior.

I caught another warning that was resetting a oAuthService:

2023-10-05 09:08:16.316 [WARN ] [ce.googletts.internal.GoogleCloudAPI] - Error initializing Google Cloud TTS service: An unexpected IOException occurred: java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: Buffering capacity 2097152 exceeded

Would you be able to write a PR for it?

I think that one can be caused by the configurable limit of the TTS cache, that one can be changed in “System Settings/Voice”.

I tried changing it in “System Settings/Voice” - it didn’t help. I opened an issue - [google tts] Missing service configuration · Issue #15746 · openhab/openhab-addons · GitHub.

1 Like

Great, they will know better what is the proper solution.