mirror of
https://github.com/chliny/hass-tencentcloud-asr.git
synced 2026-07-26 00:53:57 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1cd7fff72 | ||
|
|
17fb066906 | ||
|
|
dc331904f2 | ||
|
|
bf4fa5b25c | ||
|
|
51e2b0a23a | ||
|
|
1af6717403 | ||
|
|
4e3959f6a5 | ||
|
|
2cef7baa1a | ||
|
|
1cc7277816 | ||
|
|
6cba77700d |
@@ -1,6 +1,10 @@
|
|||||||
# hass-tencentcloud-asr
|
# hass-tencentcloud-asr
|
||||||
|
|
||||||
腾讯云语音识别服务 homeassistantstt集成
|
腾讯云语音识别服务 homeassistant stt集成
|
||||||
|
|
||||||
|
[![GitHub release][releases-shield]][releases]
|
||||||
|
[![Github downloads][downloads-shield]][releases]
|
||||||
|
[![HACS][hacs-shield]][hacs]
|
||||||
|
|
||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
@@ -8,8 +12,29 @@
|
|||||||
- HACS -> 集成 -> 右上解选项 -> 自定义存储库
|
- HACS -> 集成 -> 右上解选项 -> 自定义存储库
|
||||||
- 存储库: https://github.com/chliny/hass-tencentcloud-asr
|
- 存储库: https://github.com/chliny/hass-tencentcloud-asr
|
||||||
- 类别: 集成
|
- 类别: 集成
|
||||||
- 浏览并下载存储库 -> 搜索 Tencent Cloud ASR 并下载
|
- 浏览并下载存储库 -> 搜索 TencentCloud ASR 并下载
|
||||||
- 重启Homeassistant
|
- 重启homeassistant
|
||||||
- Homeassistant 添加集成
|
- homeassistant 添加集成
|
||||||
- 设置 -> 设备与服务 -> 添加集成 -> 搜索 Tencent Cloud ASR -> 填入腾讯云API密钥和Secret
|
- 设置 -> 设备与服务 -> 添加集成 -> 搜索 TencentCloud ASR -> 填入腾讯云API密钥和Secret
|
||||||
- 提交后稍等片刻,即可看到`tencentcloud_asr`实体
|
- 提交后稍等片刻,即可看到`tencentcloud_asr`实体
|
||||||
|
|
||||||
|
## 支持模型
|
||||||
|
|
||||||
|
| 模型 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
|16k_zh| 中文通用|
|
||||||
|
|16k_zh-PY|中英粤|
|
||||||
|
|16k_en|英语|
|
||||||
|
|16k_yue|粤语|
|
||||||
|
|16k_zh_dialect|多方言,支持23种方言(上海话、四川话、武汉话、贵阳话、昆明话、西安话、郑州话、太原话、兰州话、银川话、西宁话、南京话、合肥话、南昌话、长沙话、苏州话、杭州话、济南话、天津话、石家庄话、黑龙江话、吉林话、辽宁话)|
|
||||||
|
|
||||||
|
- 更多模型详细说明,请参考[腾讯云文档](https://cloud.tencent.com/document/product/1093/35646)
|
||||||
|
- 默认模型: `16k_zh`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[releases-shield]: https://img.shields.io/github/v/release/chliny/hass-tencentcloud-asr?style=flat-square
|
||||||
|
[downloads-shield]: https://img.shields.io/github/downloads/chliny/hass-tencentcloud-asr/total?style=flat-square
|
||||||
|
[releases]: https://github.com/chliny/hass-tencentcloud-asr/releases
|
||||||
|
[hacs-shield]: https://img.shields.io/badge/HACS-Default-41BDF5.svg?style=flat-square
|
||||||
|
[hacs]: https://github.com/hacs/integration
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
|
import logging
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from .tencentcloud_api import DefaultModel
|
||||||
|
|
||||||
DOMAIN = "tencentcloud_asr"
|
DOMAIN = "tencentcloud_asr"
|
||||||
|
|
||||||
PLATFORMS = (Platform.STT,)
|
PLATFORMS = (Platform.STT,)
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
# const key
|
# const key
|
||||||
SecretIdKey = "secretid"
|
SecretIdKey = "secretid"
|
||||||
@@ -13,9 +16,21 @@ ModelKey = "model"
|
|||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
|
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
|
||||||
|
if not config_entry.update_listeners:
|
||||||
|
config_entry.add_update_listener(async_update_options)
|
||||||
|
config_data = {**config_entry.data, **config_entry.options}
|
||||||
|
model = config_data.get(ModelKey, DefaultModel)
|
||||||
|
hass.data[ModelKey] = model
|
||||||
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
async def async_update_options(hass: HomeAssistant, config_entry: ConfigEntry):
|
||||||
|
config_data = {**config_entry.data, **config_entry.options}
|
||||||
|
model = config_data.get(ModelKey, DefaultModel)
|
||||||
|
_LOGGER.debug("update model:%s", model)
|
||||||
|
hass.data[ModelKey] = model
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry):
|
async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry):
|
||||||
return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS)
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
import voluptuous as vol
|
|
||||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
|
||||||
from typing import Any, Dict
|
|
||||||
import logging
|
import logging
|
||||||
from .tencentcloud_api import Modules, DefaultModel
|
import voluptuous as vol
|
||||||
|
from typing import Any, Dict
|
||||||
|
from homeassistant.core import callback
|
||||||
|
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult, OptionsFlow, ConfigEntry
|
||||||
|
from homeassistant.helpers.selector import SelectSelector, SelectSelectorConfig, SelectOptionDict
|
||||||
|
|
||||||
|
from .tencentcloud_api import ModuleSupportLanguage, DefaultModel
|
||||||
from .tencentcloud_api import TencentCloudAsrAPi
|
from .tencentcloud_api import TencentCloudAsrAPi
|
||||||
from . import SecretIdKey, SecretKeyKey, ModelKey
|
from . import SecretIdKey, SecretKeyKey, ModelKey
|
||||||
|
|
||||||
|
|
||||||
from . import DOMAIN
|
from . import DOMAIN
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
modelSelector = SelectSelector(
|
||||||
|
SelectSelectorConfig(
|
||||||
|
options=[
|
||||||
|
SelectOptionDict(value=model_id, label=model_id) for model_id in ModuleSupportLanguage
|
||||||
|
],
|
||||||
|
translation_key="model_descriptions",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
async def async_step_user(self, user_input: dict[str, Any] | None = None) -> ConfigFlowResult:
|
async def async_step_user(self, user_input: dict[str, Any] | None = None) -> ConfigFlowResult:
|
||||||
errors: Dict[str, str] = {}
|
errors: Dict[str, str] = {}
|
||||||
@@ -27,14 +38,35 @@ class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
|
|||||||
if not errors:
|
if not errors:
|
||||||
return self.async_create_entry(title=DOMAIN, data=user_input)
|
return self.async_create_entry(title=DOMAIN, data=user_input)
|
||||||
|
|
||||||
return self.async_show_form(
|
config_schema = vol.Schema(
|
||||||
step_id="user",
|
{
|
||||||
data_schema=vol.Schema(
|
vol.Required(SecretIdKey): str,
|
||||||
{
|
vol.Required(SecretKeyKey): str,
|
||||||
vol.Required(SecretIdKey): str,
|
vol.Required(ModelKey, default=DefaultModel): modelSelector,
|
||||||
vol.Required(SecretKeyKey): str,
|
})
|
||||||
vol.Optional(ModelKey, default=DefaultModel): vol.In(Modules.keys()),
|
|
||||||
},
|
return self.async_show_form(step_id="user", data_schema=config_schema, errors=errors)
|
||||||
),
|
|
||||||
errors=errors
|
@staticmethod
|
||||||
)
|
@callback
|
||||||
|
def async_get_options_flow(config_entry: ConfigEntry):
|
||||||
|
return TencentCloudAsrOptionFlow(config_entry)
|
||||||
|
|
||||||
|
|
||||||
|
class TencentCloudAsrOptionFlow(OptionsFlow):
|
||||||
|
def __init__(self, config_entry: ConfigEntry):
|
||||||
|
self._config_entry = config_entry
|
||||||
|
|
||||||
|
async def async_step_init(self, user_input=None):
|
||||||
|
return await self.async_step_user()
|
||||||
|
|
||||||
|
async def async_step_user(self, user_input=None):
|
||||||
|
if not user_input:
|
||||||
|
user_input = {**self._config_entry.data, **self._config_entry.options}
|
||||||
|
else:
|
||||||
|
return self.async_create_entry(title=DOMAIN, data=user_input)
|
||||||
|
model = user_input.get(ModelKey, DefaultModel)
|
||||||
|
config_schema = vol.Schema({
|
||||||
|
vol.Optional(ModelKey, default=model): modelSelector,
|
||||||
|
})
|
||||||
|
return self.async_show_form(step_id="user", data_schema=config_schema, errors={})
|
||||||
|
|||||||
@@ -16,5 +16,5 @@
|
|||||||
"loggers": [
|
"loggers": [
|
||||||
"tencentcloud_asr"
|
"tencentcloud_asr"
|
||||||
],
|
],
|
||||||
"version": "0.0.1"
|
"version": "0.1.1"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,15 +29,14 @@ class ASRSTT(stt.SpeechToTextEntity):
|
|||||||
secretKey = config_entry.data.get(SecretKeyKey, "")
|
secretKey = config_entry.data.get(SecretKeyKey, "")
|
||||||
self.tencentCloudApi = TencentCloudAsrAPi(secretId, secretKey)
|
self.tencentCloudApi = TencentCloudAsrAPi(secretId, secretKey)
|
||||||
|
|
||||||
self.model: str = config_entry.data.get(ModelKey, DefaultModel)
|
|
||||||
# self._attr_name = f"TencentCloud Asr id: ({secretId})"
|
|
||||||
self._attr_unique_id = f"tencentcloud_asr_stt"
|
self._attr_unique_id = f"tencentcloud_asr_stt"
|
||||||
self._attr_name = f"TencentCloud Asr STT"
|
self._attr_name = f"TencentCloud Asr STT"
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_languages(self) -> list[str]:
|
def supported_languages(self) -> list[str]:
|
||||||
return ModuleSupportLanguage.get(self.model, ["zh"])
|
model: str = self.hass.data.get(ModelKey, DefaultModel)
|
||||||
|
return ModuleSupportLanguage.get(model, ["zh"])
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def supported_formats(self) -> list[stt.AudioFormats]:
|
def supported_formats(self) -> list[stt.AudioFormats]:
|
||||||
@@ -69,8 +68,9 @@ class ASRSTT(stt.SpeechToTextEntity):
|
|||||||
audio += chunk
|
audio += chunk
|
||||||
|
|
||||||
data = base64.b64encode(audio).decode("utf8", "ignore").strip()
|
data = base64.b64encode(audio).decode("utf8", "ignore").strip()
|
||||||
_LOGGER.debug(f"process_audio_stream transcribe: {data}")
|
model: str = self.hass.data.get(ModelKey, DefaultModel)
|
||||||
ret, result = await self.hass.async_add_executor_job(partial(self.tencentCloudApi.SentenceRecognition, self.model, data))
|
_LOGGER.debug(f"process_audio_stream transcribe: {data} {model}")
|
||||||
|
ret, result = await self.hass.async_add_executor_job(partial(self.tencentCloudApi.SentenceRecognition, model, data))
|
||||||
if not ret:
|
if not ret:
|
||||||
return stt.SpeechResult(result, stt.SpeechResultState.ERROR)
|
return stt.SpeechResult(result, stt.SpeechResultState.ERROR)
|
||||||
if not result:
|
if not result:
|
||||||
|
|||||||
@@ -10,18 +10,11 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
SentenceRecognitionSourceTypePost = 1
|
SentenceRecognitionSourceTypePost = 1
|
||||||
SentenceRecognitionSourceTypeURL = 0
|
SentenceRecognitionSourceTypeURL = 0
|
||||||
Modules = {
|
|
||||||
"16k_zh": "中文",
|
|
||||||
"16k_zh-PY": "中英粤",
|
|
||||||
"16k_en": "英语",
|
|
||||||
"16k_yue": "粤语",
|
|
||||||
"16k_zh_dialect": "多方言",
|
|
||||||
}
|
|
||||||
ModuleSupportLanguage = {
|
ModuleSupportLanguage = {
|
||||||
"16k_zh": ["zh"],
|
"16k_zh": ["zh-cn"],
|
||||||
"16k_zh-PY": ["zh", "en", "yue"],
|
"16k_zh-PY": ["zh-cn", "en", "zh-hk"],
|
||||||
"16k_en": ["en"],
|
"16k_en": ["en"],
|
||||||
"16k_yue": ["yue"],
|
"16k_yue": ["zh-hk"],
|
||||||
"16k_zh_dialect": ["zh"],
|
"16k_zh_dialect": ["zh"],
|
||||||
}
|
}
|
||||||
DefaultModel = "16k_zh"
|
DefaultModel = "16k_zh"
|
||||||
|
|||||||
@@ -8,8 +8,29 @@
|
|||||||
"secretid": "tencentcloud asr secretid",
|
"secretid": "tencentcloud asr secretid",
|
||||||
"secretkey": "tencnetcloud asr secretkey",
|
"secretkey": "tencnetcloud asr secretkey",
|
||||||
"model": "model"
|
"model": "model"
|
||||||
|
},
|
||||||
|
"description": "The integration is based on [Tencent Cloud API](https://cloud.tencent.com/document/product/1093/35646)."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"model": "model"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"model_descriptions": {
|
||||||
|
"options": {
|
||||||
|
"16k_zh": "16k_zh Chinese",
|
||||||
|
"16k_zh-PY": "16k_zh-PY - Chinese, English, and Cantonese",
|
||||||
|
"16k_en": "16k_en - English",
|
||||||
|
"16k_yue": "16k_yue - Cantonese",
|
||||||
|
"16k_zh_dialect": "16k_zh_dialect - Chinese dialects"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,29 @@
|
|||||||
"secretid": "请输入腾讯云ASR服务secretid",
|
"secretid": "请输入腾讯云ASR服务secretid",
|
||||||
"secretkey": "请输入腾讯云ASR服务secretkey",
|
"secretkey": "请输入腾讯云ASR服务secretkey",
|
||||||
"model": "模型"
|
"model": "模型"
|
||||||
|
},
|
||||||
|
"description": "此集成基于腾讯云API, 具体见[腾讯云文档](https://cloud.tencent.com/document/product/1093/35646)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"step": {
|
||||||
|
"user": {
|
||||||
|
"data": {
|
||||||
|
"model": "模型"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"selector": {
|
||||||
|
"model_descriptions": {
|
||||||
|
"options": {
|
||||||
|
"16k_zh": "16k_zh - 中文通用",
|
||||||
|
"16k_zh-PY": "16k_zh-PY - 中英粤",
|
||||||
|
"16k_en": "16k_en - 英语",
|
||||||
|
"16k_yue": "16k_yue - 粤语",
|
||||||
|
"16k_zh_dialect": "16k_zh_dialect - 中文多方言"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user