Home assistant (#97)

* add home assistant

* update home assistant remark

* update config

* update:优化文档

---------

Co-authored-by: ck3 <kyriechen03@qq.com>
Co-authored-by: Kyrie Chen <794103684@qq.com>
Co-authored-by: hrz <1710360675@qq.com>
This commit is contained in:
欣南科技
2025-02-20 22:40:41 +08:00
committed by GitHub
co-authored by ck3 Kyrie Chen hrz
parent de793625e4
commit afa469c08c
6 changed files with 106 additions and 21 deletions
+29 -17
View File
@@ -80,15 +80,16 @@ server:
### LLM ### LLM
| 类型 | 平台名称 | 使用方式 | 收费模式 | 备注 | | 类型 | 平台名称 | 使用方式 | 收费模式 | 备注 |
|:---:|:------------------:|:-----------:|:--------:|:-----------------------------------------------------------------:| |:---:|:------------------:|:---------------------:|:--------:|:-----------------------------------------------------------------:|
| LLM | 阿里百炼 (AliLLM) | openai 接口调用 | 消耗 token | [点击申请密钥](https://bailian.console.aliyun.com/?apiKey=1#/api-key) | | LLM | 阿里百炼 (AliLLM) | openai 接口调用 | 消耗 token | [点击申请密钥](https://bailian.console.aliyun.com/?apiKey=1#/api-key) |
| LLM | 深度求索 (DeepSeekLLM) | openai 接口调用 | 消耗 token | [点击申请密钥](https://platform.deepseek.com/) | | LLM | 深度求索 (DeepSeekLLM) | openai 接口调用 | 消耗 token | [点击申请密钥](https://platform.deepseek.com/) |
| LLM | 智谱(ChatGLMLLM | openai 接口调用 | 免费 | 虽然免费,仍需[点击申请密钥](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) | | LLM | 智谱(ChatGLMLLM | openai 接口调用 | 免费 | 虽然免费,仍需[点击申请密钥](https://bigmodel.cn/usercenter/proj-mgmt/apikeys) |
| LLM | OllamaLLM | ollama 接口调用 | 免费/自定义 | 需预先下载模型(`ollama pull`),服务地址:`http://localhost:11434` | | LLM | OllamaLLM | ollama 接口调用 | 免费/自定义 | 需预先下载模型(`ollama pull`),服务地址:`http://localhost:11434` |
| LLM | DifyLLM | dify 接口调用 | 消耗 token | 本地化部署,注意配置提示词需在 Dify 控制台设置 | | LLM | DifyLLM | dify 接口调用 | 消耗 token | 本地化部署,注意配置提示词需在 Dify 控制台设置 |
| LLM | GeminiLLM | gemini 接口调用 | 免费 | [点击申请密钥](https://aistudio.google.com/apikey) | | LLM | GeminiLLM | gemini 接口调用 | 免费 | [点击申请密钥](https://aistudio.google.com/apikey) |
| LLM | CozeLLM | coze 接口调用 | 消耗 token | 需提供 bot_id、user_id 及个人令牌 | | LLM | CozeLLM | coze 接口调用 | 消耗 token | 需提供 bot_id、user_id 及个人令牌 |
| LLM | Home Assistant | homeassistant语音助手接口调用 | 免费 | 需提供home assistant令牌 |
实际上,任何支持 openai 接口调用的 LLM 均可接入使用。 实际上,任何支持 openai 接口调用的 LLM 均可接入使用。
@@ -127,11 +128,8 @@ server:
### 一、[部署文档](./docs/Deployment.md) ### 一、[部署文档](./docs/Deployment.md)
1. 1.**[本地源码运行](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%89%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C)**
*
*[本地源码运行](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%B8%89%E6%9C%AC%E5%9C%B0%E6%BA%90%E7%A0%81%E8%BF%90%E8%A1%8C)
**
适合熟悉 Conda 环境或希望从零搭建运行环境的用户。 适合熟悉 Conda 环境或希望从零搭建运行环境的用户。
对于对响应速度要求较高的场景,推荐使用本地源码运行方式以降低额外开销。 对于对响应速度要求较高的场景,推荐使用本地源码运行方式以降低额外开销。
@@ -152,7 +150,7 @@ server:
### 2、我想通过小智控制电灯、空调、远程开关机等操作 💡 ### 2、我想通过小智控制电灯、空调、远程开关机等操作 💡
建议:在配置文件中将 `LLM` 设置为 `DifyLLM`通过 `Dify` 编排智能体来实现相关控制。 建议:在配置文件中将 `LLM` 设置为 `HomeAssistant`,通过 调用`HomeAssistant`接口实现相关控制。
### 3、我说话很慢,停顿时小智老是抢话 🗣️ ### 3、我说话很慢,停顿时小智老是抢话 🗣️
@@ -166,7 +164,21 @@ VAD:
min_silence_duration_ms: 700 # 如果说话停顿较长,可将此值调大 min_silence_duration_ms: 700 # 如果说话停顿较长,可将此值调大
``` ```
### 4、如何提高小智对话响应速度? ⚡ ### 4、为什么我说的话,小智识别出来很多韩文、日文、英文?🇰🇷
建议:检查一下`models/SenseVoiceSmall`是否已经有`model.pt`文件,如果没有就要下载,查看这里[下载语音识别模型文件](docs/Deployment.md#模型文件)
### 5、为什么会出现“TTS 任务出错 文件不存在”?📁
建议:检查一下是否正确使用`conda` 安装了`libopus``ffmpeg`库。
如果没有安装,就安装
```
conda install conda-forge::libopus
conda install conda-forge::ffmpeg
```
### 6、如何提高小智对话响应速度? ⚡
本项目默认配置为低成本方案,建议初学者先使用默认免费模型,解决“跑得动”的问题,再优化“跑得快”。 本项目默认配置为低成本方案,建议初学者先使用默认免费模型,解决“跑得动”的问题,再优化“跑得快”。
如需提升响应速度,可尝试更换各组件。以下为各组件的响应速度测试数据(仅供参考,不构成承诺): 如需提升响应速度,可尝试更换各组件。以下为各组件的响应速度测试数据(仅供参考,不构成承诺):
@@ -224,7 +236,7 @@ TTS 性能排行:
- LLM`AliLLM` - LLM`AliLLM`
- TTS`DoubaoTTS` - TTS`DoubaoTTS`
### 5、更多问题,可联系我们反馈 💬 ### 7、更多问题,可联系我们反馈 💬
![图片](docs/images/wechat.jpg) ![图片](docs/images/wechat.jpg)
+6
View File
@@ -128,6 +128,12 @@ LLM:
user_id: 你的user_id user_id: 你的user_id
base_url: "https://api.coze.cn/open_api/v2/chat" # 服务地址 base_url: "https://api.coze.cn/open_api/v2/chat" # 服务地址
personal_access_token: 你的coze个人令牌 personal_access_token: 你的coze个人令牌
HomeAssistant:
# 定义LLM API类型
type: homeassistant
base_url: http://homeassistant.local:8123
agent_id: conversation.chatgpt
api_key: 你的home assistant api访问令牌
TTS: TTS:
# 当前支持的type为edge、doubao,可自行适配 # 当前支持的type为edge、doubao,可自行适配
EdgeTTS: EdgeTTS:
@@ -0,0 +1,62 @@
import requests
from requests.exceptions import RequestException
from config.logger import setup_logging
from core.providers.llm.base import LLMProviderBase
TAG = __name__
logger = setup_logging()
class LLMProvider(LLMProviderBase):
def __init__(self, config):
self.agent_id = config.get("agent_id") # 对应 agent_id
self.api_key = config.get("api_key")
self.base_url = config.get("base_url", config.get("url")) # 默认使用 base_url
self.api_url = f"{self.base_url}/api/conversation/process" # 拼接完整的 API URL
def response(self, session_id, dialogue):
print(dialogue)
try:
# home assistant语音助手自带意图,无需使用xiaozhi ai自带的,只需要把用户说的话传递给home assistant即可
# 提取最后一个 role 为 'user' 的 content
input_text = None
if isinstance(dialogue, list): # 确保 dialogue 是一个列表
# 逆序遍历,找到最后一个 role 为 'user' 的消息
for message in reversed(dialogue):
if message.get("role") == "user": # 找到 role 为 'user' 的消息
input_text = message.get("content", "")
break # 找到后立即退出循环
# 构造请求数据
payload = {
"text": input_text,
"agent_id": self.agent_id,
"conversation_id": session_id # 使用 session_id 作为 conversation_id
}
# 设置请求头
headers = {
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
}
# 发起 POST 请求
response = requests.post(self.api_url, json=payload, headers=headers)
# 检查请求是否成功
response.raise_for_status()
# 解析返回数据
data = response.json()
speech = data.get("response", {}).get("speech", {}).get("plain", {}).get("speech", "")
# 返回生成的内容
if speech:
yield speech
else:
logger.bind(tag=TAG).warning("API 返回数据中没有 speech 内容")
except RequestException as e:
logger.bind(tag=TAG).error(f"HTTP 请求错误: {e}")
except Exception as e:
logger.bind(tag=TAG).error(f"生成响应时出错: {e}")
+7 -1
View File
@@ -9,8 +9,11 @@ from pydantic import BaseModel, Field, conint, model_validator
from typing_extensions import Annotated from typing_extensions import Annotated
from datetime import datetime from datetime import datetime
from typing import Literal from typing import Literal
# from base import TTSProviderBase
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
from config.logger import setup_logging
TAG = __name__
logger = setup_logging()
class ServeReferenceAudio(BaseModel): class ServeReferenceAudio(BaseModel):
@@ -86,6 +89,9 @@ class TTSProvider(TTSProviderBase):
self.channels = config.get("channels",1) self.channels = config.get("channels",1)
self.rate = config.get("rate",44100) self.rate = config.get("rate",44100)
self.api_key = config.get("api_key","YOUR_API_KEY") self.api_key = config.get("api_key","YOUR_API_KEY")
if not self.api_key or "" in self.api_key:
logger.bind(tag=TAG).error("你还没配置FishSpeech TTS的密钥,请在配置文件中配置密钥,否则无法正常工作")
return
self.normalize = config.get("normalize",True) self.normalize = config.get("normalize",True)
self.max_new_tokens = config.get("max_new_tokens",1024) self.max_new_tokens = config.get("max_new_tokens",1024)
self.chunk_length = config.get("chunk_length",200) self.chunk_length = config.get("chunk_length",200)
-2
View File
@@ -1,7 +1,5 @@
import os import os
import uuid import uuid
import json
import base64
import requests import requests
from datetime import datetime from datetime import datetime
from core.providers.tts.base import TTSProviderBase from core.providers.tts.base import TTSProviderBase
+2 -1
View File
@@ -15,4 +15,5 @@ aiohttp==3.9.3
aiohttp_cors==0.7.0 aiohttp_cors==0.7.0
ormsgpack==1.7.0 ormsgpack==1.7.0
ruamel.yaml==0.18.10 ruamel.yaml==0.18.10
loguru==0.7.3 loguru==0.7.3
requests>=2.0.0