Google TTS addon for OH2

@gbicskei

I’ve downloaded the binding you created and placed in my ADDONS folder

I’ve created and downloaded the JSON file through the Google Cloud tool

Started OH and let the GTTS folder get created

Placed the JSON file in the newly created GTTS folder

Went into Paper UI and adjusted the settings in SERVICES > VOICE > GOOGLE TTS SERVICE

Went into Paper UI and selected GOOGLE TTS SERVICE as my default TTS SERVICE

Attempted to look at voices yet NONE of the GOOGLE voices are displayed in my list…they are only the POLLY TTS voices event when GOOGLE TTS is selected.

Went to the OPENHAB.LOG file and found the following:

2018-07-14 14:04:39.915 [ERROR] [b.voice.gtts.internal.GoogleCloudAPI] - Error initializing the service using D:\OpenHab\userdata\gtts\xxxxxxxxxxxxxxxxxxxxx.json
java.lang.IllegalStateException: Could not find TLS ALPN provider; no working netty-tcnative, Conscrypt, or Jetty NPN/ALPN available
	at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.defaultSslProvider(GrpcSslContexts.java:256) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.configure(GrpcSslContexts.java:171) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.forClient(GrpcSslContexts.java:120) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder$NettyTransportFactory$DefaultNettyTransportCreationParamsFilterFactory.<init>(NettyChannelBuilder.java:558) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder$NettyTransportFactory$DefaultNettyTransportCreationParamsFilterFactory.<init>(NettyChannelBuilder.java:551) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder$NettyTransportFactory.<init>(NettyChannelBuilder.java:489) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder.buildTransportFactory(NettyChannelBuilder.java:337) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at io.grpc.internal.AbstractManagedChannelImplBuilder.build(AbstractManagedChannelImplBuilder.java:390) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createSingleChannel(InstantiatingGrpcChannelProvider.java:206) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.createChannel(InstantiatingGrpcChannelProvider.java:157) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.api.gax.grpc.InstantiatingGrpcChannelProvider.getTransportChannel(InstantiatingGrpcChannelProvider.java:149) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.api.gax.rpc.ClientContext.create(ClientContext.java:151) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.cloud.texttospeech.v1beta1.stub.GrpcTextToSpeechStub.create(GrpcTextToSpeechStub.java:74) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.cloud.texttospeech.v1beta1.stub.TextToSpeechStubSettings.createStub(TextToSpeechStubSettings.java:99) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.cloud.texttospeech.v1beta1.TextToSpeechClient.<init>(TextToSpeechClient.java:128) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at com.google.cloud.texttospeech.v1beta1.TextToSpeechClient.create(TextToSpeechClient.java:109) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at org.openhab.voice.gtts.internal.GoogleCloudAPI.setConfig(GoogleCloudAPI.java:99) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at org.openhab.voice.gtts.internal.GoogleTTSService.updateConfig(GoogleTTSService.java:196) [264:org.openhab.voice.gtts:2.4.0.201807131451]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
	at org.apache.felix.scr.impl.inject.BaseMethod.invokeMethod(BaseMethod.java:229) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.inject.BaseMethod.access$500(BaseMethod.java:39) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.inject.BaseMethod$Resolved.invoke(BaseMethod.java:650) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.inject.BaseMethod.invoke(BaseMethod.java:506) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.inject.ActivateMethod.invoke(ActivateMethod.java:307) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.inject.ActivateMethod.invoke(ActivateMethod.java:299) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.SingleComponentManager.invokeModifiedMethod(SingleComponentManager.java:772) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.SingleComponentManager.modify(SingleComponentManager.java:727) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.SingleComponentManager.reconfigure(SingleComponentManager.java:645) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.SingleComponentManager.reconfigure(SingleComponentManager.java:609) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.configurationUpdated(ConfigurableComponentHolder.java:426) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.RegionConfigurationSupport.configurationEvent(RegionConfigurationSupport.java:284) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.scr.impl.manager.RegionConfigurationSupport$1.configurationEvent(RegionConfigurationSupport.java:89) [42:org.apache.felix.scr:2.0.12]
	at org.apache.felix.cm.impl.ConfigurationManager$FireConfigurationEvent.sendEvent(ConfigurationManager.java:2090) [7:org.apache.felix.configadmin:1.8.16]
	at org.apache.felix.cm.impl.ConfigurationManager$FireConfigurationEvent.run(ConfigurationManager.java:2058) [7:org.apache.felix.configadmin:1.8.16]
	at org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:141) [7:org.apache.felix.configadmin:1.8.16]
	at org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:109) [7:org.apache.felix.configadmin:1.8.16]
	at java.lang.Thread.run(Thread.java:748) [?:?]

OH VERSION: 2.3 Build 1204
JAVA VERSION: 1.80_161
OS: WINDOWS

Any suggestions??

Squid

@KidSquid
Please make sure your Windows OS is x86_64. It will NOT run on ARM. See supported platforms for details.
If this is OK please turn on TRACE logging on io.grpc:
In OH console:
log:set TRACE io.grpc
Then restart the Google Cloud TTS Service:
bundle:restart Service_ID
and send me the logs. I am looking for the point where the GRPC code is trying to get the default SSL provider in your environment, and it fails for some reason…
Thx

I have done what you’ve requested and attached the log to this post.

Thanks for your assistance.

Squid

@KidSquid
Your Windows is a 32 bit version.

could not load a native library: io_grpc_netty_shaded_netty_tcnative_windows_x86_32

Unfortunately tcnative doesn’t have 32bit builds which is a dependency for Google Cloud Java.

I am running Windows Server which is x64

@KidSquid Check the JDK too? Is it 64 bit as well? The grpc-netty library sees it as x86_32. I’ve added some trace to the service startup, to check this. Download the new binary pls. It is building as I’m writing this…

@gbicskei

Hello -

Sorry for the slow response, real life got in the way! :slight_smile:

I double checked my system and sure enough the JDK I had installed was 32bit, so I have installed the 64 bit version and updated the JAVA_HOME variable to point to the new 64 bit install.

I am still running into issues.

I downloaded the new version of the binding and installed it…in the log I see an error message about the TTS not being enabled on the API, so I click the link provided and enable the TTS.

I then waited quite a bit and still can not seem to get things to work.

As I stated earlier…I see the GOOGLE TTS shows in the SYSTEM display, yet all the voices I see are from POLLY TTS

image

Log File…

https://we.tl/I6pwihWowa

@KidSquid
Hi,
The good news is that the addon can now communicate to Google. The problem is that you haven’t set up the project and the permissions on the Google side. Follow the documentation to do that (there is a link even in the log file you’ve uploaded).

@gbicskei

Thanks for pointing that out, looks like I skipped the billing part of the setup.

Once question, in looking at the voices in OH, the drop down seems to have combined all of the POLLY TTS voices along with the GOOGLE TTS voices…I assume I’m seeing GOOGLE voices as a couple now have WAVENET proceeding the name. I take it there is not a way to have the drop down in SYSTEM only show the voices available to the TTS engine you have selected?

Squid

@KidSquid I’m afraid that feature is out-of-scope for a voice service addon…

Hi everyone

Just stumbled on this post

Are you all saying this addon give Openhab the ability to send predetermined text too a Google home so it can speak it out?

Yes, this will allow you to use the GOOGLE TTS service to provide Text to Speech.

If you want to hear it via your Google home, you’ll also need to install the CHROMECAST binding to turn the device into an AUDIO SINK.

Squid

2 Likes

Hi Thanks for the reply

I already have the chromecast binding installed my Google home does speak my system notifications but

I have been using a separate tts app writing my output saving the file as a wav and then converting it to mp3 adding it too the sounds folder and using a rule too play when needed bit of a ball ache tbh

I will look into this

Just so you know you can use any of the other TTS bindings like POLLY TTS as well.

The new voices in the GOOGLE TTS are really good and probably some of the best available.

Squid

Do they both use the google homes native voice?

I believe that is only available through the GOOGLE TTS

1 Like

Ok

Am I able too run this on a rpi 3 b+ this is the first I have looked into this sort of thing

The manual for using Mary Tts says not compatible with rpi needs a real server so I was wondering if this was the same although I’m assuming googles servers are taking the load of processing?

I do not believe so…check a few posts up as I believe someone else had the issue as well.

I will look now

I do have another computer running 24/7 it’s more powerful than a rpi could it be middle manned?

Get the pi send the request too the bigger computer and so on

RPI NOT SUPPORTED
Thus, the following are not supported:

Android
Alpine Linux (due to netty-tcnative requiring glibc, which is not present on Alpine)
Raspberry Pi (since it runs on the ARM architecture)
Google App Engine Standard Java 7

Thanks for the help on that anyway @KidSquid I will save it for a maby todo as it would require moving from the rpi too a different server and I have only just moved it off a Windows machine and on too a rpi

So, I decided to test Google TTS, I have previously used both voicerss and lately Polly.

I can get it to work if I use default in ‘say’ command, e.g. say(“Testing”), however, since I need to address Sonos players in my rules, (bedroom etc), I suppose I have to define also tts service and voice. This is what I have done with Polly;
say( “Testar”,“pollytts:Astrid”, “sonos:CONNECT:toilet”) which works fine with Polly.

But for Google TTS?
In default setup, I have chosen “Google Cloud TTS Service” and default voice “sv-SE-Standard-A - svenska (Sverige)”
How does this translate into a say argument? I have tried different options, I think “gtts” should be the service, but what about voice? Whatever I try, I get an exceptions e.g.
say( “Sändare knapp 1”,“gtts:svSE”, “sonos:PLAY1:bedroom”)
say( “Sändare knapp 1”,“gtts:sv-SE”, “sonos:PLAY1:bedroom”)
say( “Sändare Knapp 1”,“gtts:sv-SE-Standard-A”, “sonos:PLAY1:bedroom”)

Gives

13:16:23.140 [WARN ] [.core.voice.internal.VoiceManagerImpl] - Error saying 'Sändare Knapp 1': Unable to find a voice for language sv
org.eclipse.smarthome.core.voice.TTSException: Unable to find a voice for language sv
        at org.eclipse.smarthome.core.voice.internal.VoiceManagerImpl.say(VoiceManagerImpl.java:206) ~[?:?]
        at org.eclipse.smarthome.model.script.actions.Voice.say(Voice.java:121) ~[?:?]
        at org.eclipse.smarthome.model.script.actions.Voice.say(Voice.java:102) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1085) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1060) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1046) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:991) ~[?:?]
        at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:901) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:864) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:223) ~[?:?]
        at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:227) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]
        at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:227) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:491) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:255) ~[?:?]
        at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:227) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:446) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:227) ~[?:?]
        at org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:227) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) ~[?:?]
        at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:189) ~[?:?]
        at org.eclipse.smarthome.model.script.runtime.internal.engine.ScriptImpl.execute(ScriptImpl.java:82) ~[?:?]
        at org.eclipse.smarthome.model.rule.runtime.internal.engine.RuleEngineImpl.lambda$2(RuleEngineImpl.java:345) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) [?:?]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) [?:?]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
        at java.lang.Thread.run(Thread.java:748) [?:?]
13:100:

Best would be if there was a way of being able to select sink without having to specify TTS/voice but I haven’t found a way of doing this either.