feat: add ASR filtering options

This commit is contained in:
chliny
2026-07-19 22:50:02 +08:00
parent 667a735fe4
commit 1a05335b3c
6 changed files with 128 additions and 12 deletions
@@ -13,6 +13,10 @@ _LOGGER = logging.getLogger(__name__)
SecretIdKey = "secretid"
SecretKeyKey = "secretkey"
ModelKey = "model"
FilterDirtyKey = "filter_dirty"
FilterModalKey = "filter_modal"
FilterPuncKey = "filter_punc"
ConvertNumModeKey = "convert_num_mode"
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
@@ -3,11 +3,24 @@ 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 homeassistant.helpers.selector import (
BooleanSelector,
SelectOptionDict,
SelectSelector,
SelectSelectorConfig,
)
from .tencentcloud_api import ModuleSupportLanguage, DefaultModel
from .tencentcloud_api import TencentCloudAsrAPi
from . import SecretIdKey, SecretKeyKey, ModelKey
from . import (
ConvertNumModeKey,
FilterDirtyKey,
FilterModalKey,
FilterPuncKey,
ModelKey,
SecretIdKey,
SecretKeyKey,
)
from . import DOMAIN
_LOGGER = logging.getLogger(__name__)
@@ -22,6 +35,17 @@ modelSelector = SelectSelector(
)
)
filterDirtySelector = SelectSelector(
SelectSelectorConfig(
options=[
SelectOptionDict(value="0", label="0"),
SelectOptionDict(value="1", label="1"),
SelectOptionDict(value="2", label="2"),
],
translation_key="filter_dirty_descriptions",
)
)
class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
async def async_step_user(self, user_input: dict[str, Any] | None = None) -> ConfigFlowResult:
@@ -43,6 +67,10 @@ class ConfigFlowHandler(ConfigFlow, domain=DOMAIN):
vol.Required(SecretIdKey): str,
vol.Required(SecretKeyKey): str,
vol.Required(ModelKey, default=DefaultModel): modelSelector,
vol.Required(FilterDirtyKey, default="0"): filterDirtySelector,
vol.Required(FilterModalKey, default=False): BooleanSelector(),
vol.Required(FilterPuncKey, default=False): BooleanSelector(),
vol.Required(ConvertNumModeKey, default=True): BooleanSelector(),
})
return self.async_show_form(step_id="user", data_schema=config_schema, errors=errors)
@@ -68,5 +96,21 @@ class TencentCloudAsrOptionFlow(OptionsFlow):
model = user_input.get(ModelKey, DefaultModel)
config_schema = vol.Schema({
vol.Optional(ModelKey, default=model): modelSelector,
vol.Required(
FilterDirtyKey,
default=user_input.get(FilterDirtyKey, "0"),
): filterDirtySelector,
vol.Required(
FilterModalKey,
default=user_input.get(FilterModalKey, False),
): BooleanSelector(),
vol.Required(
FilterPuncKey,
default=user_input.get(FilterPuncKey, False),
): BooleanSelector(),
vol.Required(
ConvertNumModeKey,
default=user_input.get(ConvertNumModeKey, True),
): BooleanSelector(),
})
return self.async_show_form(step_id="user", data_schema=config_schema, errors={})
+29 -4
View File
@@ -10,7 +10,15 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .tencentcloud_api import TencentCloudAsrAPi
from .tencentcloud_api import ModuleSupportLanguage
from .tencentcloud_api import DefaultModel
from . import SecretIdKey, SecretKeyKey, ModelKey
from . import (
ConvertNumModeKey,
FilterDirtyKey,
FilterModalKey,
FilterPuncKey,
ModelKey,
SecretIdKey,
SecretKeyKey,
)
_LOGGER = logging.getLogger(__name__)
@@ -32,6 +40,7 @@ class ASRSTT(stt.SpeechToTextEntity):
self._attr_unique_id = f"tencentcloud_asr_stt"
self._attr_name = f"TencentCloud Asr STT"
self.hass = hass
self.config_entry = config_entry
@property
def supported_languages(self) -> list[str]:
@@ -71,9 +80,25 @@ class ASRSTT(stt.SpeechToTextEntity):
audio += chunk
data = base64.b64encode(audio).decode("utf8", "ignore").strip()
model: str = self.hass.data.get(ModelKey, DefaultModel)
_LOGGER.debug(f"process_audio_stream transcribe: {data} {model}")
ret, result = await self.hass.async_add_executor_job(partial(self.tencentCloudApi.SentenceRecognition, model, data))
config = {**self.config_entry.data, **self.config_entry.options}
model: str = config.get(ModelKey, DefaultModel)
_LOGGER.debug(
"process_audio_stream transcribe: audio_bytes=%s model=%s",
len(audio),
model,
)
ret, result = await self.hass.async_add_executor_job(
partial(
self.tencentCloudApi.SentenceRecognition,
model,
data,
len(audio),
config.get(FilterDirtyKey, "0"),
config.get(FilterModalKey, False),
config.get(FilterPuncKey, False),
config.get(ConvertNumModeKey, True),
)
)
if not ret:
return stt.SpeechResult(result, stt.SpeechResultState.ERROR)
if not result:
@@ -43,7 +43,16 @@ class TencentCloudAsrAPi(object):
region = ""
self.asrClient = AsrClient(cred, region)
def SentenceRecognition(self, engSerViceType, data: str) -> (tuple[bool, str | None]):
def SentenceRecognition(
self,
engSerViceType,
data: str,
data_len: int,
filter_dirty: str,
filter_modal: bool,
filter_punc: bool,
convert_num_mode: bool,
) -> tuple[bool, str | None]:
req = SentenceRecognitionRequest()
req.EngSerViceType = engSerViceType
req.SourceType = SentenceRecognitionSourceTypePost
@@ -52,7 +61,11 @@ class TencentCloudAsrAPi(object):
req.SubServiceType = 2
req.UsrAudioKey = ""
req.Data = data
req.DataLen = len(data)
req.DataLen = data_len
req.FilterDirty = int(filter_dirty)
req.FilterModal = int(filter_modal)
req.FilterPunc = int(filter_punc)
req.ConvertNumMode = int(convert_num_mode)
try:
res: SentenceRecognitionResponse = self.asrClient.SentenceRecognition(req)
return True, res.Result
@@ -7,7 +7,11 @@
"data": {
"secretid": "tencentcloud asr secretid",
"secretkey": "tencnetcloud asr secretkey",
"model": "model"
"model": "model",
"filter_dirty": "Dirty word handling",
"filter_modal": "Filter filler words such as um and uh",
"filter_punc": "Filter sentence-ending punctuation",
"convert_num_mode": "Smart Arabic numeral conversion"
},
"description": "The integration is based on [Tencent Cloud API](https://cloud.tencent.com/document/product/1093/35646)."
}
@@ -17,12 +21,23 @@
"step": {
"user": {
"data": {
"model": "model"
"model": "model",
"filter_dirty": "Dirty word handling",
"filter_modal": "Filter filler words such as um and uh",
"filter_punc": "Filter sentence-ending punctuation",
"convert_num_mode": "Smart Arabic numeral conversion"
}
}
}
},
"selector": {
"filter_dirty_descriptions": {
"options": {
"0": "Do not filter dirty words",
"1": "Filter dirty words",
"2": "Replace dirty words with *"
}
},
"model_descriptions": {
"options": {
"8k_zh": "8k_zh - Chinese telephone audio",
@@ -7,7 +7,11 @@
"data": {
"secretid": "请输入腾讯云ASR服务secretid",
"secretkey": "请输入腾讯云ASR服务secretkey",
"model": "模型"
"model": "模型",
"filter_dirty": "脏词处理方式",
"filter_modal": "过滤“嗯、啊”等语气词",
"filter_punc": "过滤句末标点",
"convert_num_mode": "阿拉伯数字智能转换"
},
"description": "此集成基于腾讯云API, 具体见[腾讯云文档](https://cloud.tencent.com/document/product/1093/35646)"
}
@@ -17,12 +21,23 @@
"step": {
"user": {
"data": {
"model": "模型"
"model": "模型",
"filter_dirty": "脏词处理方式",
"filter_modal": "过滤“嗯、啊”等语气词",
"filter_punc": "过滤句末标点",
"convert_num_mode": "阿拉伯数字智能转换"
}
}
}
},
"selector": {
"filter_dirty_descriptions": {
"options": {
"0": "不过滤脏词",
"1": "过滤脏词",
"2": "将脏词替换为 *"
}
},
"model_descriptions": {
"options": {
"8k_zh": "8k_zh - 中文电话通用",