import logging import httpx from haunt_fm.config import settings logger = logging.getLogger(__name__) async def _ha_request(method: str, path: str, **kwargs) -> dict: """Make an authenticated request to Home Assistant REST API.""" headers = { "Authorization": f"Bearer {settings.ha_token}", "Content-Type": "application/json", } async with httpx.AsyncClient(timeout=10) as client: resp = await client.request( method, f"{settings.ha_url}{path}", headers=headers, **kwargs ) resp.raise_for_status() if resp.content: return resp.json() return {} async def is_ha_reachable() -> bool: """Check if Home Assistant is reachable.""" try: await _ha_request("GET", "/api/") return True except Exception: return False async def play_media_on_speaker( media_content_id: str, speaker_entity: str, media_content_type: str = "music", ) -> None: """Play a media item on a speaker via HA media_player service.""" await _ha_request( "POST", "/api/services/media_player/play_media", json={ "entity_id": speaker_entity, "media_content_id": media_content_id, "media_content_type": media_content_type, }, ) logger.info("Playing %s on %s", media_content_id, speaker_entity) async def search_and_play( artist: str, title: str, speaker_entity: str, ) -> bool: """Search Music Assistant for a track and play it. Uses the mass.search service to find the track, then plays it. """ try: # Use Music Assistant search via HA result = await _ha_request( "POST", "/api/services/mass/search", json={ "name": f"{artist} {title}", "media_type": "track", "limit": 1, }, ) logger.info("MA search result for '%s - %s': %s", artist, title, result) return True except Exception: logger.exception("Failed to search MA for %s - %s", artist, title) return False async def play_playlist_on_speaker( tracks: list[dict], speaker_entity: str, ) -> None: """Play a list of tracks on a speaker. Each track dict has 'artist' and 'title'. Enqueues tracks via Music Assistant. """ if not tracks: return for i, track in enumerate(tracks): try: if i == 0: # Play first track await _ha_request( "POST", "/api/services/media_player/play_media", json={ "entity_id": speaker_entity, "media_content_id": f"{track['artist']} - {track['title']}", "media_content_type": "music", }, ) else: # Enqueue subsequent tracks await _ha_request( "POST", "/api/services/media_player/play_media", json={ "entity_id": speaker_entity, "media_content_id": f"{track['artist']} - {track['title']}", "media_content_type": "music", "enqueue": "add", }, ) except Exception: logger.exception("Failed to enqueue %s - %s", track["artist"], track["title"])