mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-30 05:13:59 +08:00
refactor: 合并 HA 设备控制插件为 hass_state 模块
This commit is contained in:
@@ -286,8 +286,7 @@ Intent:
|
||||
# play_music是服务器自带的音乐播放,hass_play_music是通过home assistant控制的独立外部程序音乐播放
|
||||
# 如果用了hass_play_music,就不要开启play_music,两者只留一个
|
||||
- play_music
|
||||
#- hass_get_state
|
||||
#- hass_set_state
|
||||
#- hass_state
|
||||
#- hass_play_music
|
||||
|
||||
Memory:
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
import httpx
|
||||
from config.logger import setup_logging
|
||||
from plugins_func.functions.hass_init import initialize_hass_handler
|
||||
from plugins_func.register import register_function, ToolType, ActionResponse, Action
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from core.connection import ConnectionHandler
|
||||
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
hass_get_state_function_desc = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "hass_get_state",
|
||||
"description": "获取homeassistant里设备的状态,包括查询灯光亮度、颜色、色温,媒体播放器的音量,设备的暂停、继续操作",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity_id": {
|
||||
"type": "string",
|
||||
"description": "需要操作的设备id,homeassistant里的entity_id",
|
||||
}
|
||||
},
|
||||
"required": ["entity_id"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@register_function("hass_get_state", hass_get_state_function_desc, ToolType.SYSTEM_CTL)
|
||||
async def hass_get_state(conn: "ConnectionHandler", entity_id=""):
|
||||
try:
|
||||
ha_response = await handle_hass_get_state(conn, entity_id)
|
||||
return ActionResponse(Action.REQLLM, ha_response, None)
|
||||
except httpx.TimeoutException:
|
||||
logger.bind(tag=TAG).error("获取Home Assistant状态超时")
|
||||
return ActionResponse(Action.ERROR, "请求超时", None)
|
||||
except Exception as e:
|
||||
error_msg = f"执行Home Assistant操作失败"
|
||||
logger.bind(tag=TAG).error(error_msg)
|
||||
return ActionResponse(Action.ERROR, error_msg, None)
|
||||
|
||||
|
||||
async def handle_hass_get_state(conn: "ConnectionHandler", entity_id):
|
||||
ha_config = initialize_hass_handler(conn)
|
||||
api_key = ha_config.get("api_key")
|
||||
base_url = ha_config.get("base_url")
|
||||
url = f"{base_url}/api/states/{entity_id}"
|
||||
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
|
||||
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(5.0, connect=3.0)) as client:
|
||||
response = await client.get(url, headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
responsetext = "设备状态:" + response.json()["state"] + " "
|
||||
logger.bind(tag=TAG).info(f"api返回内容: {response.json()}")
|
||||
|
||||
if "media_title" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "正在播放的是:"
|
||||
+ str(response.json()["attributes"]["media_title"])
|
||||
+ " "
|
||||
)
|
||||
if "volume_level" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "音量是:"
|
||||
+ str(response.json()["attributes"]["volume_level"])
|
||||
+ " "
|
||||
)
|
||||
if "color_temp_kelvin" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "色温是:"
|
||||
+ str(response.json()["attributes"]["color_temp_kelvin"])
|
||||
+ " "
|
||||
)
|
||||
if "rgb_color" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "rgb颜色是:"
|
||||
+ str(response.json()["attributes"]["rgb_color"])
|
||||
+ " "
|
||||
)
|
||||
if "brightness" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "亮度是:"
|
||||
+ str(response.json()["attributes"]["brightness"])
|
||||
+ " "
|
||||
)
|
||||
logger.bind(tag=TAG).info(f"查询返回内容: {responsetext}")
|
||||
return responsetext
|
||||
else:
|
||||
return f"切换失败,错误码: {response.status_code}"
|
||||
@@ -16,7 +16,7 @@ def append_devices_to_prompt(conn):
|
||||
config_source = (
|
||||
"home_assistant"
|
||||
if plugins_config.get("home_assistant")
|
||||
else "hass_get_state"
|
||||
else "hass_state"
|
||||
)
|
||||
|
||||
if "hass_get_state" in funcs or "hass_set_state" in funcs:
|
||||
@@ -36,7 +36,7 @@ def initialize_hass_handler(conn):
|
||||
plugins_config = conn.config.get("plugins", {})
|
||||
# 确定配置来源
|
||||
config_source = (
|
||||
"home_assistant" if plugins_config.get("home_assistant") else "hass_get_state"
|
||||
"home_assistant" if plugins_config.get("home_assistant") else "hass_state"
|
||||
)
|
||||
if not plugins_config.get(config_source):
|
||||
return ha_config
|
||||
|
||||
+87
@@ -10,6 +10,24 @@ if TYPE_CHECKING:
|
||||
TAG = __name__
|
||||
logger = setup_logging()
|
||||
|
||||
hass_get_state_function_desc = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "hass_get_state",
|
||||
"description": "获取homeassistant里设备的状态,包括查询灯光亮度、颜色、色温,媒体播放器的音量,设备的暂停、继续操作",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"entity_id": {
|
||||
"type": "string",
|
||||
"description": "需要操作的设备id,homeassistant里的entity_id",
|
||||
}
|
||||
},
|
||||
"required": ["entity_id"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
hass_set_state_function_desc = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
@@ -52,6 +70,20 @@ hass_set_state_function_desc = {
|
||||
}
|
||||
|
||||
|
||||
@register_function("hass_get_state", hass_get_state_function_desc, ToolType.SYSTEM_CTL)
|
||||
async def hass_get_state(conn: "ConnectionHandler", entity_id=""):
|
||||
try:
|
||||
ha_response = await handle_hass_get_state(conn, entity_id)
|
||||
return ActionResponse(Action.REQLLM, ha_response, None)
|
||||
except httpx.TimeoutException:
|
||||
logger.bind(tag=TAG).error("获取Home Assistant状态超时")
|
||||
return ActionResponse(Action.ERROR, "请求超时", None)
|
||||
except Exception as e:
|
||||
error_msg = f"执行Home Assistant操作失败"
|
||||
logger.bind(tag=TAG).error(error_msg)
|
||||
return ActionResponse(Action.ERROR, error_msg, None)
|
||||
|
||||
|
||||
@register_function("hass_set_state", hass_set_state_function_desc, ToolType.SYSTEM_CTL)
|
||||
async def hass_set_state(conn: "ConnectionHandler", entity_id="", state=None):
|
||||
if state is None:
|
||||
@@ -68,6 +100,61 @@ async def hass_set_state(conn: "ConnectionHandler", entity_id="", state=None):
|
||||
return ActionResponse(Action.ERROR, error_msg, None)
|
||||
|
||||
|
||||
async def handle_hass_get_state(conn: "ConnectionHandler", entity_id):
|
||||
ha_config = initialize_hass_handler(conn)
|
||||
api_key = ha_config.get("api_key")
|
||||
base_url = ha_config.get("base_url")
|
||||
url = f"{base_url}/api/states/{entity_id}"
|
||||
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
|
||||
|
||||
async with httpx.AsyncClient(timeout=httpx.Timeout(5.0, connect=3.0)) as client:
|
||||
response = await client.get(url, headers=headers)
|
||||
|
||||
if response.status_code == 200:
|
||||
responsetext = "设备状态:" + response.json()["state"] + " "
|
||||
logger.bind(tag=TAG).info(f"api返回内容: {response.json()}")
|
||||
|
||||
if "media_title" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "正在播放的是:"
|
||||
+ str(response.json()["attributes"]["media_title"])
|
||||
+ " "
|
||||
)
|
||||
if "volume_level" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "音量是:"
|
||||
+ str(response.json()["attributes"]["volume_level"])
|
||||
+ " "
|
||||
)
|
||||
if "color_temp_kelvin" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "色温是:"
|
||||
+ str(response.json()["attributes"]["color_temp_kelvin"])
|
||||
+ " "
|
||||
)
|
||||
if "rgb_color" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "rgb颜色是:"
|
||||
+ str(response.json()["attributes"]["rgb_color"])
|
||||
+ " "
|
||||
)
|
||||
if "brightness" in response.json()["attributes"]:
|
||||
responsetext = (
|
||||
responsetext
|
||||
+ "亮度是:"
|
||||
+ str(response.json()["attributes"]["brightness"])
|
||||
+ " "
|
||||
)
|
||||
logger.bind(tag=TAG).info(f"查询返回内容: {responsetext}")
|
||||
return responsetext
|
||||
else:
|
||||
return f"切换失败,错误码: {response.status_code}"
|
||||
|
||||
|
||||
async def handle_hass_set_state(conn: "ConnectionHandler", entity_id, state):
|
||||
ha_config = initialize_hass_handler(conn)
|
||||
api_key = ha_config.get("api_key")
|
||||
Reference in New Issue
Block a user