[OH3.2] Pico Text-to-Speech Docker usage

  • Platform information:
    • Hardware: Oracle Virtual Machine (2xCPU/2GB RAM)
    • OS: Kali Linux
    • Java Runtime Environment: JDK 11.0.14
    • openHAB version: 3.2 (Docker)
  • Issue of the topic:
    I want to use Pico TTS to get OH audio feedback.
  1. I installed Pico on the HOST following the documentation:
sudo apt-get install libttspico-utils
  1. On host I have the pico2wave binary available and executable.
  2. I installed the Pico Text-to-Speech bundle via BASIC UI. Afterwards I could select the Pico TTS in the voice settings of administarstion panel.
  3. I created a rule which should execute
say("Lautstärke wurde erhöht");

QUESTION: Do I need to link the Pico into the docker? Or do I need to install the Pico inside the docker? But doing this, it won’t be persistent.
Any recommendation or advise from you guys is appreciated!

  • Please post configurations (if applicable):
    • Items configuration related to the issue
    • Sitemap configuration related to the issue
    • Rules code related to the issue
    • Services configuration related to the issue
  • If logs where generated please post these here using code fences:
    I get this exeception in my openhab.log:

2022-02-24 15:47:58.670 [WARN ] [core.voice.internal.VoiceManagerImpl] - Error saying 'Lautstärke wurde erhöht': org.openhab.core.audio.AudioException: Error while executing '[Ljava.lang.String;@7102ba6c' org.openhab.core.voice.TTSException: org.openhab.core.audio.AudioException: Error while executing '[Ljava.lang.String;@7102ba6c' at org.openhab.voice.picotts.internal.PicoTTSService.synthesize(PicoTTSService.java:76) ~[?:?] at org.openhab.core.voice.internal.VoiceManagerImpl.say(VoiceManagerImpl.java:223) ~[?:?] at org.openhab.core.model.script.actions.Voice.say(Voice.java:121) ~[?:?] at org.openhab.core.model.script.actions.Voice.say(Voice.java:39) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1192) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeOperation(XbaseInterpreter.java:1167) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._invokeFeature(XbaseInterpreter.java:1153) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.invokeFeature(XbaseInterpreter.java:1098) ~[?:?] at org.openhab.core.model.script.interpreter.ScriptInterpreter.invokeFeature(ScriptInterpreter.java:151) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:1008) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:971) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:247) ~[?:?] at org.openhab.core.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:227) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter._doEvaluate(XbaseInterpreter.java:475) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.doEvaluate(XbaseInterpreter.java:251) ~[?:?] at org.openhab.core.model.script.interpreter.ScriptInterpreter.doEvaluate(ScriptInterpreter.java:226) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:227) ~[?:?] at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:213) ~[?:?] at org.openhab.core.model.script.runtime.internal.engine.ScriptImpl.execute(ScriptImpl.java:80) ~[?:?] at org.openhab.core.model.script.runtime.internal.engine.DSLScriptEngine.eval(DSLScriptEngine.java:131) ~[?:?] at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.lambda$0(ScriptActionHandler.java:62) ~[?:?] at java.util.Optional.ifPresent(Optional.java:183) [?:?] at org.openhab.core.automation.module.script.internal.handler.ScriptActionHandler.execute(ScriptActionHandler.java:59) [bundleFile:?] at org.openhab.core.automation.internal.RuleEngineImpl.executeActions(RuleEngineImpl.java:1180) [bundleFile:?] at org.openhab.core.automation.internal.RuleEngineImpl.runRule(RuleEngineImpl.java:988) [bundleFile:?] at org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData.run(TriggerHandlerCallbackImpl.java:89) [bundleFile:?] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?] at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?] at java.lang.Thread.run(Thread.java:829) [?:?] Caused by: org.openhab.core.audio.AudioException: Error while executing '[Ljava.lang.String;@7102ba6c' at org.openhab.voice.picotts.internal.PicoTTSAudioStream.createInputStream(PicoTTSAudioStream.java:68) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSAudioStream.<init>(PicoTTSAudioStream.java:48) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSService.synthesize(PicoTTSService.java:74) ~[?:?] ... 36 more Caused by: java.io.IOException: Cannot run program "pico2wave": error=2, No such file or directory at java.lang.ProcessBuilder.start(ProcessBuilder.java:1128) ~[?:?] at java.lang.ProcessBuilder.start(ProcessBuilder.java:1071) ~[?:?] at java.lang.Runtime.exec(Runtime.java:592) ~[?:?] at java.lang.Runtime.exec(Runtime.java:451) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSAudioStream.createInputStream(PicoTTSAudioStream.java:61) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSAudioStream.<init>(PicoTTSAudioStream.java:48) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSService.synthesize(PicoTTSService.java:74) ~[?:?] ... 36 more Caused by: java.io.IOException: error=2, No such file or directory at java.lang.ProcessImpl.forkAndExec(Native Method) ~[?:?] at java.lang.ProcessImpl.<init>(ProcessImpl.java:340) ~[?:?] at java.lang.ProcessImpl.start(ProcessImpl.java:271) ~[?:?] at java.lang.ProcessBuilder.start(ProcessBuilder.java:1107) ~[?:?] at java.lang.ProcessBuilder.start(ProcessBuilder.java:1071) ~[?:?] at java.lang.Runtime.exec(Runtime.java:592) ~[?:?] at java.lang.Runtime.exec(Runtime.java:451) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSAudioStream.createInputStream(PicoTTSAudioStream.java:61) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSAudioStream.<init>(PicoTTSAudioStream.java:48) ~[?:?] at org.openhab.voice.picotts.internal.PicoTTSService.synthesize(PicoTTSService.java:74) ~[?:?] ... 36 more

=> Caused by: java.io.IOException: Cannot run program “pico2wave”: error=2, No such file or directory

Hello,

Yes, the pico2wave binary must be directly available from the openHAB program running inside the docker instance.
So, as I understand docker, either you install it inside the docker container, or you create a fake “pico2wave” script inside the docker who will communicate with the host (by ssh, or through a named pipe for example). In both case you have to manually modify the docker instance and you have to take care of the persistence issue you mentioned.

Another solution to circumvent the persistence issue could be to NOT USE use the “say” command, and instead use the exec binding to call the host and its pico2wave binary by SSH (but, I don’t know, is the SSH command available from inside the docker instance ?)

Hi Gwendal,

thanks for your reply.
I installed Pico inside the docker with these commands:

root@docker:/openhab# wget http://ftp.fr.debian.org/debian/pool/non-free/s/svox/libttspico0_1.0%2Bgit20130326-12_amd64.deb
root@docker:/openhab# wget http://ftp.fr.debian.org/debian/pool/non-free/s/svox/libttspico-utils_1.0%2Bgit20130326-12_amd64.deb
root@docker:/openhab# wget http://ftp.fr.debian.org/debian/pool/non-free/s/svox/libttspico-dev_1.0%2Bgit20130326-12_amd64.deb
root@docker:/openhab# wget http://ftp.fr.debian.org/debian/pool/non-free/s/svox/libttspico-data_1.0%2Bgit20130326-12_all.deb
root@docker:/openhab# dpkg -i libttspico-data_1.0+git20130326-12_all.deb
root@docker:/openhab# dpkg -i libttspico0_1.0+git20130326-12_amd64.deb
root@docker:/openhab# apt-get install libpopt0
root@docker:/openhab# dpkg -i libttspico-utils_1.0+git20130326-12_amd64.deb

Finally I was able to execute the say command without any exception.
At least on one chromecast device.
Now I need to figure out how to say it on my Bose Soundtouch devices, since tOH does not recognize those as audio sink.
But this is another topic …