configurable speaker based on device_id
This commit is contained in:
parent
b6c0d6d752
commit
5dec833544
@ -20,7 +20,8 @@ class Agent:
|
|||||||
history: list = None,
|
history: list = None,
|
||||||
tools: Union[None, list] = None,
|
tools: Union[None, list] = None,
|
||||||
prompts: Union[None, list] = None,
|
prompts: Union[None, list] = None,
|
||||||
language: str = "en"
|
language: str = "en",
|
||||||
|
device_id: str = ""
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Ask the agent a question.
|
Ask the agent a question.
|
||||||
|
|||||||
@ -23,6 +23,7 @@ with open("config.yml", "r", encoding="utf8") as file:
|
|||||||
def load_plugins(config):
|
def load_plugins(config):
|
||||||
tools = []
|
tools = []
|
||||||
prompts = []
|
prompts = []
|
||||||
|
plugin_instances = []
|
||||||
|
|
||||||
for plugin_folder in os.listdir("./" + PLUGINS_FOLDER):
|
for plugin_folder in os.listdir("./" + PLUGINS_FOLDER):
|
||||||
if (
|
if (
|
||||||
@ -33,15 +34,16 @@ def load_plugins(config):
|
|||||||
module_path = f"{PLUGINS_FOLDER}.{plugin_folder}.plugin"
|
module_path = f"{PLUGINS_FOLDER}.{plugin_folder}.plugin"
|
||||||
module = importlib.import_module(module_path)
|
module = importlib.import_module(module_path)
|
||||||
plugin = module.Plugin(config)
|
plugin = module.Plugin(config)
|
||||||
|
plugin_instances.append(plugin)
|
||||||
tools += plugin.tools()
|
tools += plugin.tools()
|
||||||
prompt = plugin.prompt()
|
prompt = plugin.prompt()
|
||||||
if prompt is not None:
|
if prompt is not None:
|
||||||
prompts.append(prompt)
|
prompts.append(prompt)
|
||||||
|
|
||||||
return tools, prompts
|
return tools, prompts, plugin_instances
|
||||||
|
|
||||||
|
|
||||||
tools, prompts = load_plugins(config)
|
tools, prompts, plugins = load_plugins(config)
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
app.mount("/static", StaticFiles(directory="static"), name="static")
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
@ -89,5 +91,9 @@ def ask(q: Question):
|
|||||||
if q.history:
|
if q.history:
|
||||||
history = [q.model_dump() for q in q.history]
|
history = [q.model_dump() for q in q.history]
|
||||||
|
|
||||||
answer = agent.ask(question=q.question, history=history, tools=tools, prompts=prompts, language=q.language)
|
# Set device_id on all plugin instances
|
||||||
|
for plugin in plugins:
|
||||||
|
plugin.device_id = q.device_id
|
||||||
|
|
||||||
|
answer = agent.ask(question=q.question, history=history, tools=tools, prompts=prompts, language=q.language, device_id=q.device_id)
|
||||||
return {"question": q.question, "answer": answer, "history": q.history}
|
return {"question": q.question, "answer": answer, "history": q.history}
|
||||||
|
|||||||
@ -7,6 +7,7 @@ class BasePlugin:
|
|||||||
def __init__(self, config: dict) -> None:
|
def __init__(self, config: dict) -> None:
|
||||||
self.config = config
|
self.config = config
|
||||||
self.homeassistant = HomeAssistant(config)
|
self.homeassistant = HomeAssistant(config)
|
||||||
|
self.device_id = ""
|
||||||
|
|
||||||
def prompt(self) -> str | None:
|
def prompt(self) -> str | None:
|
||||||
return
|
return
|
||||||
|
|||||||
@ -15,17 +15,32 @@ class PlayMusicInput(BaseModel):
|
|||||||
class Plugin(BasePlugin):
|
class Plugin(BasePlugin):
|
||||||
def __init__(self, config: dict) -> None:
|
def __init__(self, config: dict) -> None:
|
||||||
super().__init__(config=config)
|
super().__init__(config=config)
|
||||||
self.entity_id = self.config["plugins"]["music"]["default_speaker"]
|
|
||||||
|
|
||||||
self.spotify = spotipy.Spotify(
|
self.spotify = spotipy.Spotify(
|
||||||
auth_manager=SpotifyOAuth(
|
auth_manager=SpotifyOAuth(
|
||||||
scope="user-library-read",
|
scope="user-library-read",
|
||||||
redirect_uri="http://localhost:8080",
|
redirect_uri="http://localhost:8080",
|
||||||
client_id=self.config["plugins"]["music"]["spotify_client_id"],
|
client_id=self.config["plugins"]["music"]["spotify_client_id"],
|
||||||
client_secret=self.config["plugins"]["music"]["spotify_client_secret"]
|
client_secret=self.config["plugins"]["music"]["spotify_client_secret"]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _get_speaker_for_device(self, device_id: str) -> str:
|
||||||
|
"""
|
||||||
|
Get the appropriate speaker entity_id based on device_id.
|
||||||
|
Falls back to default_speaker if device_id is not found or empty.
|
||||||
|
"""
|
||||||
|
device_speakers = self.config["plugins"]["music"].get("device_speakers", {})
|
||||||
|
|
||||||
|
if device_id and device_id in device_speakers:
|
||||||
|
speaker = device_speakers[device_id]
|
||||||
|
logging.info(f"Using device-specific speaker for {device_id}: {speaker}")
|
||||||
|
return speaker
|
||||||
|
|
||||||
|
default_speaker = self.config["plugins"]["music"]["default_speaker"]
|
||||||
|
logging.info(f"Using default speaker: {default_speaker}")
|
||||||
|
return default_speaker
|
||||||
|
|
||||||
def _search(self, query: str, limit: int = 10):
|
def _search(self, query: str, limit: int = 10):
|
||||||
_result = self.spotify.search(query, limit=limit)
|
_result = self.spotify.search(query, limit=limit)
|
||||||
result = []
|
result = []
|
||||||
@ -45,9 +60,10 @@ class Plugin(BasePlugin):
|
|||||||
Play music using a search query.
|
Play music using a search query.
|
||||||
"""
|
"""
|
||||||
track = self._search(input.query, limit=1)[0]
|
track = self._search(input.query, limit=1)[0]
|
||||||
logging.info(f"Playing {track['name']} by {', '.join(track['artists'])}")
|
speaker = self._get_speaker_for_device(self.device_id)
|
||||||
|
logging.info(f"Playing {track['name']} by {', '.join(track['artists'])} on {speaker}")
|
||||||
payload = {
|
payload = {
|
||||||
"entity_id": self.entity_id,
|
"entity_id": speaker,
|
||||||
"media_content_id": track["uri"],
|
"media_content_id": track["uri"],
|
||||||
"media_content_type": "music",
|
"media_content_type": "music",
|
||||||
"enqueue": "play",
|
"enqueue": "play",
|
||||||
@ -59,7 +75,8 @@ class Plugin(BasePlugin):
|
|||||||
"""
|
"""
|
||||||
Stop playback of music.
|
Stop playback of music.
|
||||||
"""
|
"""
|
||||||
|
speaker = self._get_speaker_for_device(self.device_id)
|
||||||
self.homeassistant.call_api(
|
self.homeassistant.call_api(
|
||||||
f"services/media_player/media_pause", payload={"entity_id": self.entity_id}
|
f"services/media_player/media_pause", payload={"entity_id": speaker}
|
||||||
)
|
)
|
||||||
return json.dumps({"status": "success", "message": f"Music paused."})
|
return json.dumps({"status": "success", "message": f"Music paused."})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user