configurable speaker based on device_id

This commit is contained in:
Pierre Wessman 2025-11-07 13:18:10 +01:00
parent b6c0d6d752
commit 5dec833544
4 changed files with 34 additions and 9 deletions

View File

@ -20,7 +20,8 @@ class Agent:
history: list = None,
tools: Union[None, list] = None,
prompts: Union[None, list] = None,
language: str = "en"
language: str = "en",
device_id: str = ""
):
"""
Ask the agent a question.

View File

@ -23,6 +23,7 @@ with open("config.yml", "r", encoding="utf8") as file:
def load_plugins(config):
tools = []
prompts = []
plugin_instances = []
for plugin_folder in os.listdir("./" + PLUGINS_FOLDER):
if (
@ -33,15 +34,16 @@ def load_plugins(config):
module_path = f"{PLUGINS_FOLDER}.{plugin_folder}.plugin"
module = importlib.import_module(module_path)
plugin = module.Plugin(config)
plugin_instances.append(plugin)
tools += plugin.tools()
prompt = plugin.prompt()
if prompt is not None:
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.mount("/static", StaticFiles(directory="static"), name="static")
@ -89,5 +91,9 @@ def ask(q: Question):
if 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}

View File

@ -7,6 +7,7 @@ class BasePlugin:
def __init__(self, config: dict) -> None:
self.config = config
self.homeassistant = HomeAssistant(config)
self.device_id = ""
def prompt(self) -> str | None:
return

View File

@ -15,7 +15,6 @@ class PlayMusicInput(BaseModel):
class Plugin(BasePlugin):
def __init__(self, config: dict) -> None:
super().__init__(config=config)
self.entity_id = self.config["plugins"]["music"]["default_speaker"]
self.spotify = spotipy.Spotify(
auth_manager=SpotifyOAuth(
@ -26,6 +25,22 @@ class Plugin(BasePlugin):
)
)
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):
_result = self.spotify.search(query, limit=limit)
result = []
@ -45,9 +60,10 @@ class Plugin(BasePlugin):
Play music using a search query.
"""
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 = {
"entity_id": self.entity_id,
"entity_id": speaker,
"media_content_id": track["uri"],
"media_content_type": "music",
"enqueue": "play",
@ -59,7 +75,8 @@ class Plugin(BasePlugin):
"""
Stop playback of music.
"""
speaker = self._get_speaker_for_device(self.device_id)
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."})