Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Cloud Platform component (TTS) #23629

Merged
merged 28 commits into from Jun 6, 2019
Merged
Changes from 6 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
b8d3ad5
Added Google Cloud TTS service component feature
lufton May 2, 2019
a0eee36
Added Neutral voice gender
lufton May 2, 2019
ca9f74d
Added line break at the end of files
lufton May 2, 2019
3366917
Updated CODEOWNERS, reqirements_all.txt and .coveragerc
lufton May 2, 2019
886afc3
Fixed some ci/circleci: static-check errors
lufton May 2, 2019
bdef472
Fixed some ci/circleci: static-check error
lufton May 2, 2019
9069ca1
Fixed some ci/circleci: pylint errors
lufton May 2, 2019
398704c
Fixed some ci/circleci: pylint errors
lufton May 2, 2019
4b84ad4
* made supported_options const
lufton May 3, 2019
43d12ad
Fixed import order
lufton May 3, 2019
82b7b73
* Component renamed
lufton May 3, 2019
58fd922
Changed folder name in .coveragerc
lufton May 3, 2019
4ffb391
* Removed whitespaces in blank lines
lufton May 3, 2019
6ca61bd
Removed whitespaces in blank lines
lufton May 3, 2019
c6efab9
ci/circleci: static-check
lufton May 3, 2019
885bd53
Fixed requirements_all.txt
lufton May 3, 2019
e9c96ea
Added speed, pitch and gain parameters
lufton May 3, 2019
9916fe7
Added speed, pitch and gain as supported options
lufton May 3, 2019
d69de61
Split too long line
lufton May 3, 2019
2a1d81b
* Added profiles parameter
lufton May 5, 2019
11f4708
Fixes
lufton May 5, 2019
d116e8a
Fixes
lufton May 5, 2019
40cfc8e
Fixes
lufton May 5, 2019
0fb51af
Fixes
lufton May 5, 2019
e0274df
Fixes
lufton May 5, 2019
b3e66ad
Changed options validation
lufton May 14, 2019
0e27501
Added ToggleEntity save and restore state mechanism
lufton May 18, 2019
a80fa1d
Revert "Added ToggleEntity save and restore state mechanism"
lufton May 18, 2019
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -220,6 +220,7 @@ omit =
homeassistant/components/goalfeed/*
homeassistant/components/gogogate2/cover.py
homeassistant/components/google/*
homeassistant/components/google_cloud_tts/tts.py
homeassistant/components/google_maps/device_tracker.py
homeassistant/components/google_travel_time/sensor.py
homeassistant/components/googlehome/*
@@ -86,6 +86,7 @@ homeassistant/components/gearbest/* @HerrHofrat
homeassistant/components/gitter/* @fabaff
homeassistant/components/glances/* @fabaff
homeassistant/components/gntp/* @robbiet480
homeassistant/components/google_cloud_tts/* @lufton
This conversation was marked as resolved by awarecan

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor

Name it google_cloud. In future, we may add other gcloud feature in same integration

This comment has been minimized.

Copy link
@lufton

lufton May 3, 2019

Author Contributor

Should I go ahead I rename it with next commit?

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor

Please rename it.

This comment has been minimized.

Copy link
@lufton

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor

Yes

This comment has been minimized.

Copy link
@lufton

lufton May 3, 2019

Author Contributor

Yes - make it google_cloud instead of google_cloud_tts?

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor

I will make it clear, you should change all google_cloud_tts to google_cloud in your filename, source cod, and document. We want to manage all Google Cloud API related stuff in google_cloud integration, tts just one application.

This comment has been minimized.

Copy link
@lufton

lufton May 3, 2019

Author Contributor

Thanks for clarification!

homeassistant/components/google_translate/* @awarecan
homeassistant/components/google_travel_time/* @robbiet480
homeassistant/components/googlehome/* @ludeeus
@@ -0,0 +1 @@
"""The google_cloud_tts component."""
@@ -0,0 +1,12 @@
{
"domain": "google_cloud_tts",
This conversation was marked as resolved by lufton

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor
Suggested change
"domain": "google_cloud_tts",
"domain": "google_cloud",
"name": "Google Cloud TTS",
"documentation": "https://www.home-assistant.io/components/google_cloud_tts",
"requirements": [
"google-cloud-texttospeech==0.4.0"
],
"dependencies": [],
"codeowners": [
"@lufton"
]
}
@@ -0,0 +1,119 @@
"""Support for the Google Cloud TTS service."""
import logging
import async_timeout
import voluptuous as vol
import os
import homeassistant.helpers.config_validation as cv
from homeassistant.components.tts import CONF_LANG, PLATFORM_SCHEMA, Provider

from google.cloud import texttospeech

_LOGGER = logging.getLogger(__name__)

GENDERS = [
'Neutral', 'Female', 'Male',
]
DEFAULT_GENDER = GENDERS[0]

SUPPORT_LANGUAGES = [
'en', 'da', 'nl', 'fr', 'de', 'it', 'ja', 'ko', 'nb',
'pl', 'pt', 'ru', 'sk', 'es', 'sv', 'tr', 'uk',
]
DEFAULT_LANG = SUPPORT_LANGUAGES[0]

CONF_GENDER = 'gender'
CONF_VOICE = 'voice'
CONF_KEY_FILE = 'key_file'
GOOGLE_APPLICATION_CREDENTIALS = 'GOOGLE_APPLICATION_CREDENTIALS'

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_LANG, default=DEFAULT_LANG): vol.In(SUPPORT_LANGUAGES),
vol.Optional(CONF_GENDER, default=DEFAULT_GENDER): vol.In(GENDERS),
vol.Optional(CONF_VOICE, default=''): cv.string,
vol.Optional(CONF_KEY_FILE, default=''): cv.string,
})


async def async_get_engine(hass, config):
"""Set up Google Cloud TTS component."""
return GoogleCloudTTSProvider(
hass,
config[CONF_KEY_FILE],
config[CONF_LANG],
config[CONF_GENDER],
config[CONF_VOICE]
)


class GoogleCloudTTSProvider(Provider):
"""The Google Cloud TTS API provider."""

def __init__(self, hass, key_file, lang, gender, voice):
"""Init Google Cloud TTS service."""
self.hass = hass
self._lang = lang
self._gender = gender
self._voice = voice
self.name = 'Google Cloud TTS'
path = hass.config.path(key_file)
if key_file and os.path.isfile(path):
os.environ[GOOGLE_APPLICATION_CREDENTIALS] = path
if GOOGLE_APPLICATION_CREDENTIALS not in os.environ:
This conversation was marked as resolved by lufton

This comment has been minimized.

Copy link
@ljmerza

ljmerza May 3, 2019

Contributor

Looking through the docs for this , I wouldn't use ENV as it's not very user friendly.

This comment has been minimized.

Copy link
@lufton

lufton May 3, 2019

Author Contributor

Fixed in 4b84ad4

_LOGGER.error(
"You need to specify valid"
" GOOGLE_APPLICATION_CREDENTIALS file location."
)
self.client = texttospeech.TextToSpeechClient()
self.audio_config = texttospeech.types.AudioConfig(
audio_encoding=texttospeech.enums.AudioEncoding.MP3
This conversation was marked as resolved by lufton

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor

This could be a configurable option

)

@property
def default_language(self):
"""Return the default language."""
return self._lang

@property
def supported_languages(self):
"""Return list of supported languages."""
return SUPPORT_LANGUAGES

@property
def supported_options(self):
"""Return a list of supported options."""
return ["voice", "gender"]
This conversation was marked as resolved by lufton

This comment has been minimized.

Copy link
@ljmerza

ljmerza May 3, 2019

Contributor

you have const for these

This comment has been minimized.

Copy link
@lufton

lufton May 3, 2019

Author Contributor

Fixed in 4b84ad4


async def async_get_tts_audio(self, message, language, options=None):
"""Load TTS from google."""
try:
with async_timeout.timeout(10, loop=self.hass.loop):
gender = self._gender
voice = self._voice
if options:
if CONF_GENDER in options:
gender = options[CONF_GENDER].lower().capitalize()
if CONF_VOICE in options:
voice = options[CONF_VOICE]
self.voice = texttospeech.types.VoiceSelectionParams(
language_code=language or self._lang,
name=voice,
ssml_gender={
'Neutral': texttospeech.enums.SsmlVoiceGender.NEUTRAL,
This conversation was marked as resolved by lufton

This comment has been minimized.

Copy link
@awarecan

awarecan May 3, 2019

Contributor

This dict could be a CONST

'Female': texttospeech.enums.SsmlVoiceGender.FEMALE,
'Male': texttospeech.enums.SsmlVoiceGender.MALE,
}.get(gender, DEFAULT_GENDER)
)
synthesis_input = texttospeech.types.SynthesisInput(
text=message
)
response = self.client.synthesize_speech(
synthesis_input,
self.voice,
self.audio_config
)

return "mp3", response.audio_content

except Exception as e:
_LOGGER.error("Timeout for google speech or other problem.", e)
return None, None
@@ -499,6 +499,9 @@ google-api-python-client==1.6.4
# homeassistant.components.google_pubsub
google-cloud-pubsub==0.39.1

# homeassistant.components.google_cloud_tts
google-cloud-texttospeech==0.4.0

# homeassistant.components.googlehome
googledevices==1.0.2

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.