From 2ec4bc93d5dfc8c692ac3ee134294dd02015f2c4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 13 Dec 2025 14:21:05 +0000 Subject: [PATCH 1/3] Improve error handling for Home Assistant API requests Add _safe_request method with proper error handling for: - Invalid/expired tokens (401) - Permission denied (403) - Connection timeouts - Invalid JSON responses - Network errors This provides clearer error messages to users instead of cryptic JSON parse errors. --- ha_overview.py | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/ha_overview.py b/ha_overview.py index d4cefdc..1eeb616 100644 --- a/ha_overview.py +++ b/ha_overview.py @@ -38,31 +38,44 @@ class HomeAssistantOverview: print(f"✗ Verbindungsfehler: {e}") return False + def _safe_request(self, endpoint): + """Sichere API-Anfrage mit Error-Handling""" + try: + response = requests.get(f"{self.url}{endpoint}", headers=self.headers, timeout=30) + if response.status_code == 401: + raise Exception("Token ungültig oder abgelaufen") + if response.status_code == 403: + raise Exception("Zugriff verweigert - Token hat keine Berechtigung") + if response.status_code != 200: + raise Exception(f"API-Fehler: HTTP {response.status_code}") + return response.json() + except requests.exceptions.JSONDecodeError as e: + raise Exception(f"Ungültige API-Antwort (kein JSON): {str(e)[:100]}") + except requests.exceptions.Timeout: + raise Exception("Zeitüberschreitung - Home Assistant antwortet nicht") + except requests.exceptions.ConnectionError: + raise Exception("Verbindungsfehler - Home Assistant nicht erreichbar") + def get_config(self): """Hole die Konfiguration""" - response = requests.get(f"{self.url}/api/config", headers=self.headers) - return response.json() - + return self._safe_request("/api/config") + def get_components(self): """Hole alle installierten Komponenten/Integrationen""" - response = requests.get(f"{self.url}/api/config/core", headers=self.headers) - data = response.json() + data = self._safe_request("/api/config/core") return data.get('components', []) - + def get_states(self): """Hole alle Entitäten mit ihren Zuständen""" - response = requests.get(f"{self.url}/api/states", headers=self.headers) - return response.json() - + return self._safe_request("/api/states") + def get_services(self): """Hole alle verfügbaren Services""" - response = requests.get(f"{self.url}/api/services", headers=self.headers) - return response.json() - + return self._safe_request("/api/services") + def get_events(self): """Hole alle verfügbaren Events""" - response = requests.get(f"{self.url}/api/events", headers=self.headers) - return response.json() + return self._safe_request("/api/events") def analyze_entities(self, states): """Analysiere Entitäten nach Domains""" From 1fe028f4afdc051a88e3e1847168902fbbe8bf07 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 13 Dec 2025 14:34:56 +0000 Subject: [PATCH 2/3] Add Sony Bravia TV remote card and auto-setup script - lovelace_sony_tv_remote.yaml: Ready-to-use Lovelace card template - setup_tv_remote.py: Auto-detects TV entities and generates customized card --- lovelace_sony_tv_remote.yaml | 593 +++++++++++++++++++++++++++++++++++ setup_tv_remote.py | 587 ++++++++++++++++++++++++++++++++++ 2 files changed, 1180 insertions(+) create mode 100644 lovelace_sony_tv_remote.yaml create mode 100644 setup_tv_remote.py diff --git a/lovelace_sony_tv_remote.yaml b/lovelace_sony_tv_remote.yaml new file mode 100644 index 0000000..c5178aa --- /dev/null +++ b/lovelace_sony_tv_remote.yaml @@ -0,0 +1,593 @@ +# Sony Bravia TV Fernbedienung - Lovelace Karte +# ============================================= +# ANLEITUNG: +# 1. Ersetze "media_player.sony_bravia_tv" durch deine echte Entity-ID +# 2. Kopiere den Code ab "type: picture-elements" in dein Dashboard +# (Dashboard bearbeiten -> + Karte hinzufuegen -> YAML zeigen) +# +# Um deine Entity-ID zu finden: +# Home Assistant -> Entwicklerwerkzeuge -> Zustaende -> "media_player" eintippen +# ============================================= + +type: vertical-stack +cards: + # TV Status & Info + - type: entities + title: "Sony Bravia TV" + entities: + - entity: media_player.sony_bravia_tv + name: "TV Status" + state_color: true + + # Fernbedienung + - type: grid + columns: 3 + square: false + cards: + # Power Button + - type: button + name: "Power" + icon: mdi:power + tap_action: + action: call-service + service: media_player.toggle + target: + entity_id: media_player.sony_bravia_tv + hold_action: + action: call-service + service: media_player.turn_off + target: + entity_id: media_player.sony_bravia_tv + icon_height: 40px + + # Home Button + - type: button + name: "Home" + icon: mdi:home + tap_action: + action: call-service + service: remote.send_command + data: + command: HOME + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # Source/Input + - type: button + name: "Input" + icon: mdi:import + tap_action: + action: call-service + service: remote.send_command + data: + command: INPUT + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # --- Navigation --- + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # Hoch + - type: button + name: "" + icon: mdi:chevron-up + tap_action: + action: call-service + service: remote.send_command + data: + command: UP + target: + entity_id: remote.sony_bravia_tv + icon_height: 50px + + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # Links + - type: button + name: "" + icon: mdi:chevron-left + tap_action: + action: call-service + service: remote.send_command + data: + command: LEFT + target: + entity_id: remote.sony_bravia_tv + icon_height: 50px + + # OK/Enter + - type: button + name: "OK" + icon: mdi:checkbox-blank-circle + tap_action: + action: call-service + service: remote.send_command + data: + command: CONFIRM + target: + entity_id: remote.sony_bravia_tv + icon_height: 50px + + # Rechts + - type: button + name: "" + icon: mdi:chevron-right + tap_action: + action: call-service + service: remote.send_command + data: + command: RIGHT + target: + entity_id: remote.sony_bravia_tv + icon_height: 50px + + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # Runter + - type: button + name: "" + icon: mdi:chevron-down + tap_action: + action: call-service + service: remote.send_command + data: + command: DOWN + target: + entity_id: remote.sony_bravia_tv + icon_height: 50px + + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # --- Zurueck/Options --- + # Back + - type: button + name: "Zurueck" + icon: mdi:arrow-left + tap_action: + action: call-service + service: remote.send_command + data: + command: RETURN + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # Options/Menu + - type: button + name: "Menu" + icon: mdi:menu + tap_action: + action: call-service + service: remote.send_command + data: + command: OPTIONS + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # Guide/EPG + - type: button + name: "Guide" + icon: mdi:television-guide + tap_action: + action: call-service + service: remote.send_command + data: + command: GUIDE + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # Lautstaerke & Kanaele + - type: grid + columns: 4 + square: false + cards: + # Vol+ + - type: button + name: "Vol+" + icon: mdi:volume-plus + tap_action: + action: call-service + service: media_player.volume_up + target: + entity_id: media_player.sony_bravia_tv + icon_height: 40px + + # Vol- + - type: button + name: "Vol-" + icon: mdi:volume-minus + tap_action: + action: call-service + service: media_player.volume_down + target: + entity_id: media_player.sony_bravia_tv + icon_height: 40px + + # CH+ + - type: button + name: "CH+" + icon: mdi:chevron-up-box + tap_action: + action: call-service + service: remote.send_command + data: + command: CHANNEL_UP + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # CH- + - type: button + name: "CH-" + icon: mdi:chevron-down-box + tap_action: + action: call-service + service: remote.send_command + data: + command: CHANNEL_DOWN + target: + entity_id: remote.sony_bravia_tv + icon_height: 40px + + # Mute + - type: button + name: "Mute" + icon: mdi:volume-mute + tap_action: + action: call-service + service: media_player.volume_mute + data: + is_volume_muted: true + target: + entity_id: media_player.sony_bravia_tv + icon_height: 40px + + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # Leer + - type: button + name: "" + icon: "" + tap_action: + action: none + + # Mediensteuerung + - type: grid + columns: 5 + square: false + cards: + # Rewind + - type: button + name: "" + icon: mdi:rewind + tap_action: + action: call-service + service: remote.send_command + data: + command: REWIND + target: + entity_id: remote.sony_bravia_tv + icon_height: 35px + + # Play + - type: button + name: "" + icon: mdi:play + tap_action: + action: call-service + service: media_player.media_play + target: + entity_id: media_player.sony_bravia_tv + icon_height: 35px + + # Pause + - type: button + name: "" + icon: mdi:pause + tap_action: + action: call-service + service: media_player.media_pause + target: + entity_id: media_player.sony_bravia_tv + icon_height: 35px + + # Stop + - type: button + name: "" + icon: mdi:stop + tap_action: + action: call-service + service: media_player.media_stop + target: + entity_id: media_player.sony_bravia_tv + icon_height: 35px + + # Fast Forward + - type: button + name: "" + icon: mdi:fast-forward + tap_action: + action: call-service + service: remote.send_command + data: + command: FORWARD + target: + entity_id: remote.sony_bravia_tv + icon_height: 35px + + # Farbtasten & Apps + - type: grid + columns: 4 + square: false + cards: + # Rot + - type: button + name: "" + icon: mdi:rectangle + styles: + icon: + - color: red + tap_action: + action: call-service + service: remote.send_command + data: + command: RED + target: + entity_id: remote.sony_bravia_tv + icon_height: 30px + + # Gruen + - type: button + name: "" + icon: mdi:rectangle + styles: + icon: + - color: green + tap_action: + action: call-service + service: remote.send_command + data: + command: GREEN + target: + entity_id: remote.sony_bravia_tv + icon_height: 30px + + # Gelb + - type: button + name: "" + icon: mdi:rectangle + styles: + icon: + - color: yellow + tap_action: + action: call-service + service: remote.send_command + data: + command: YELLOW + target: + entity_id: remote.sony_bravia_tv + icon_height: 30px + + # Blau + - type: button + name: "" + icon: mdi:rectangle + styles: + icon: + - color: blue + tap_action: + action: call-service + service: remote.send_command + data: + command: BLUE + target: + entity_id: remote.sony_bravia_tv + icon_height: 30px + + # Schnellzugriff Apps (optional) + - type: grid + columns: 4 + square: false + cards: + # Netflix + - type: button + name: "Netflix" + icon: mdi:netflix + tap_action: + action: call-service + service: remote.send_command + data: + command: NETFLIX + target: + entity_id: remote.sony_bravia_tv + icon_height: 35px + + # YouTube + - type: button + name: "YouTube" + icon: mdi:youtube + tap_action: + action: call-service + service: media_player.select_source + data: + source: "YouTube" + target: + entity_id: media_player.sony_bravia_tv + icon_height: 35px + + # Prime Video + - type: button + name: "Prime" + icon: mdi:amazon + tap_action: + action: call-service + service: media_player.select_source + data: + source: "Prime Video" + target: + entity_id: media_player.sony_bravia_tv + icon_height: 35px + + # Disney+ + - type: button + name: "Disney+" + icon: mdi:movie-open + tap_action: + action: call-service + service: media_player.select_source + data: + source: "Disney+" + target: + entity_id: media_player.sony_bravia_tv + icon_height: 35px + + # Nummernblock (optional - fuer Kanalwahl) + - type: grid + columns: 3 + square: true + cards: + - type: button + name: "1" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_1 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "2" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_2 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "3" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_3 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "4" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_4 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "5" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_5 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "6" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_6 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "7" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_7 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "8" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_8 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "9" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_9 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "" + tap_action: + action: none + + - type: button + name: "0" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_0 + target: + entity_id: remote.sony_bravia_tv + + - type: button + name: "" + tap_action: + action: none diff --git a/setup_tv_remote.py b/setup_tv_remote.py new file mode 100644 index 0000000..cb0bbab --- /dev/null +++ b/setup_tv_remote.py @@ -0,0 +1,587 @@ +#!/usr/bin/env python3 +""" +Sony Bravia TV Remote - Automatisches Setup +Findet deinen TV und erstellt die fertige Lovelace-Karte +""" + +import requests +import json +import os + +# === KONFIGURATION - NUR HIER ANPASSEN === +HA_URL = "http://homeassistant.local:8123" +HA_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI2YWU4NDc0YzEwNjE0YzkxOGVmZjNlODJkZWJiMjJhNCIsImlhdCI6MTc2NTYzNDU4MCwiZXhwIjoyMDgwOTk0NTgwfQ.1jHlByvkcFkMhV1LcxLxzrLcCU9ogSBUf9IQ2AbjUnk" +# ========================================= + +def get_entities(): + """Hole alle Entities von Home Assistant""" + headers = { + "Authorization": f"Bearer {HA_TOKEN}", + "Content-Type": "application/json" + } + response = requests.get(f"{HA_URL}/api/states", headers=headers, timeout=30) + response.raise_for_status() + return response.json() + +def find_sony_tv(entities): + """Finde Sony Bravia TV Entities""" + media_players = [] + remotes = [] + + for entity in entities: + eid = entity.get('entity_id', '').lower() + name = entity.get('attributes', {}).get('friendly_name', '').lower() + + # Suche nach Sony/Bravia/TV + is_sony = any(x in eid or x in name for x in ['sony', 'bravia', 'kd-55', 'kd55']) + is_tv = 'tv' in eid or 'tv' in name or 'fernseher' in name + + if entity['entity_id'].startswith('media_player.'): + if is_sony or is_tv: + media_players.append({ + 'entity_id': entity['entity_id'], + 'name': entity.get('attributes', {}).get('friendly_name', entity['entity_id']), + 'state': entity.get('state') + }) + + if entity['entity_id'].startswith('remote.'): + if is_sony or is_tv: + remotes.append({ + 'entity_id': entity['entity_id'], + 'name': entity.get('attributes', {}).get('friendly_name', entity['entity_id']), + 'state': entity.get('state') + }) + + return media_players, remotes + +def generate_lovelace_card(media_player_id, remote_id): + """Generiere die Lovelace Karte""" + + card = f'''type: vertical-stack +cards: + - type: entities + title: "Sony Bravia TV" + entities: + - entity: {media_player_id} + name: "TV Status" + state_color: true + + - type: grid + columns: 3 + square: false + cards: + - type: button + name: "Power" + icon: mdi:power + tap_action: + action: call-service + service: media_player.toggle + target: + entity_id: {media_player_id} + icon_height: 40px + + - type: button + name: "Home" + icon: mdi:home + tap_action: + action: call-service + service: remote.send_command + data: + command: HOME + target: + entity_id: {remote_id} + icon_height: 40px + + - type: button + name: "Input" + icon: mdi:import + tap_action: + action: call-service + service: remote.send_command + data: + command: INPUT + target: + entity_id: {remote_id} + icon_height: 40px + + - type: button + name: "" + tap_action: + action: none + + - type: button + icon: mdi:chevron-up + tap_action: + action: call-service + service: remote.send_command + data: + command: UP + target: + entity_id: {remote_id} + icon_height: 50px + + - type: button + name: "" + tap_action: + action: none + + - type: button + icon: mdi:chevron-left + tap_action: + action: call-service + service: remote.send_command + data: + command: LEFT + target: + entity_id: {remote_id} + icon_height: 50px + + - type: button + name: "OK" + icon: mdi:checkbox-blank-circle + tap_action: + action: call-service + service: remote.send_command + data: + command: CONFIRM + target: + entity_id: {remote_id} + icon_height: 50px + + - type: button + icon: mdi:chevron-right + tap_action: + action: call-service + service: remote.send_command + data: + command: RIGHT + target: + entity_id: {remote_id} + icon_height: 50px + + - type: button + name: "" + tap_action: + action: none + + - type: button + icon: mdi:chevron-down + tap_action: + action: call-service + service: remote.send_command + data: + command: DOWN + target: + entity_id: {remote_id} + icon_height: 50px + + - type: button + name: "" + tap_action: + action: none + + - type: button + name: "Zurueck" + icon: mdi:arrow-left + tap_action: + action: call-service + service: remote.send_command + data: + command: RETURN + target: + entity_id: {remote_id} + icon_height: 40px + + - type: button + name: "Menu" + icon: mdi:menu + tap_action: + action: call-service + service: remote.send_command + data: + command: OPTIONS + target: + entity_id: {remote_id} + icon_height: 40px + + - type: button + name: "Guide" + icon: mdi:television-guide + tap_action: + action: call-service + service: remote.send_command + data: + command: GUIDE + target: + entity_id: {remote_id} + icon_height: 40px + + - type: grid + columns: 4 + square: false + cards: + - type: button + name: "Vol+" + icon: mdi:volume-plus + tap_action: + action: call-service + service: media_player.volume_up + target: + entity_id: {media_player_id} + icon_height: 40px + + - type: button + name: "Vol-" + icon: mdi:volume-minus + tap_action: + action: call-service + service: media_player.volume_down + target: + entity_id: {media_player_id} + icon_height: 40px + + - type: button + name: "CH+" + icon: mdi:chevron-up-box + tap_action: + action: call-service + service: remote.send_command + data: + command: CHANNEL_UP + target: + entity_id: {remote_id} + icon_height: 40px + + - type: button + name: "CH-" + icon: mdi:chevron-down-box + tap_action: + action: call-service + service: remote.send_command + data: + command: CHANNEL_DOWN + target: + entity_id: {remote_id} + icon_height: 40px + + - type: button + name: "Mute" + icon: mdi:volume-mute + tap_action: + action: call-service + service: media_player.volume_mute + data: + is_volume_muted: true + target: + entity_id: {media_player_id} + icon_height: 40px + + - type: grid + columns: 5 + square: false + cards: + - type: button + icon: mdi:rewind + tap_action: + action: call-service + service: remote.send_command + data: + command: REWIND + target: + entity_id: {remote_id} + icon_height: 35px + + - type: button + icon: mdi:play + tap_action: + action: call-service + service: media_player.media_play + target: + entity_id: {media_player_id} + icon_height: 35px + + - type: button + icon: mdi:pause + tap_action: + action: call-service + service: media_player.media_pause + target: + entity_id: {media_player_id} + icon_height: 35px + + - type: button + icon: mdi:stop + tap_action: + action: call-service + service: media_player.media_stop + target: + entity_id: {media_player_id} + icon_height: 35px + + - type: button + icon: mdi:fast-forward + tap_action: + action: call-service + service: remote.send_command + data: + command: FORWARD + target: + entity_id: {remote_id} + icon_height: 35px + + - type: grid + columns: 4 + square: false + cards: + - type: button + name: "Netflix" + icon: mdi:netflix + tap_action: + action: call-service + service: remote.send_command + data: + command: NETFLIX + target: + entity_id: {remote_id} + icon_height: 35px + + - type: button + name: "YouTube" + icon: mdi:youtube + tap_action: + action: call-service + service: media_player.select_source + data: + source: "YouTube" + target: + entity_id: {media_player_id} + icon_height: 35px + + - type: button + name: "Prime" + icon: mdi:amazon + tap_action: + action: call-service + service: media_player.select_source + data: + source: "Prime Video" + target: + entity_id: {media_player_id} + icon_height: 35px + + - type: button + name: "Disney+" + icon: mdi:movie-open + tap_action: + action: call-service + service: media_player.select_source + data: + source: "Disney+" + target: + entity_id: {media_player_id} + icon_height: 35px + + - type: grid + columns: 3 + square: true + cards: + - type: button + name: "1" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_1 + target: + entity_id: {remote_id} + - type: button + name: "2" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_2 + target: + entity_id: {remote_id} + - type: button + name: "3" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_3 + target: + entity_id: {remote_id} + - type: button + name: "4" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_4 + target: + entity_id: {remote_id} + - type: button + name: "5" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_5 + target: + entity_id: {remote_id} + - type: button + name: "6" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_6 + target: + entity_id: {remote_id} + - type: button + name: "7" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_7 + target: + entity_id: {remote_id} + - type: button + name: "8" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_8 + target: + entity_id: {remote_id} + - type: button + name: "9" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_9 + target: + entity_id: {remote_id} + - type: button + name: "" + tap_action: + action: none + - type: button + name: "0" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_0 + target: + entity_id: {remote_id} + - type: button + name: "" + tap_action: + action: none +''' + return card + +def main(): + print("=" * 60) + print("SONY BRAVIA TV - AUTOMATISCHES LOVELACE SETUP") + print("=" * 60) + print() + + print("Verbinde mit Home Assistant...") + try: + entities = get_entities() + print(f"Gefunden: {len(entities)} Entities") + except Exception as e: + print(f"FEHLER: {e}") + print() + print("Moegliche Loesungen:") + print("1. Pruefe ob Home Assistant laeuft") + print("2. Pruefe die URL und den Token") + return + + print() + print("Suche nach Sony TV...") + media_players, remotes = find_sony_tv(entities) + + if not media_players: + print("WARNUNG: Kein Sony TV Media Player gefunden!") + print() + print("Alle gefundenen Media Player:") + for e in entities: + if e['entity_id'].startswith('media_player.'): + name = e.get('attributes', {}).get('friendly_name', '') + print(f" - {e['entity_id']} ({name})") + print() + media_player_id = input("Gib die media_player Entity-ID ein: ").strip() + else: + print(f"Gefunden: {len(media_players)} Media Player") + for i, mp in enumerate(media_players): + print(f" [{i+1}] {mp['entity_id']} - {mp['name']} ({mp['state']})") + + if len(media_players) == 1: + media_player_id = media_players[0]['entity_id'] + else: + choice = input("Waehle [1-{}]: ".format(len(media_players))).strip() + media_player_id = media_players[int(choice)-1]['entity_id'] + + if not remotes: + print("WARNUNG: Keine Sony TV Remote gefunden!") + print() + print("Alle gefundenen Remotes:") + for e in entities: + if e['entity_id'].startswith('remote.'): + name = e.get('attributes', {}).get('friendly_name', '') + print(f" - {e['entity_id']} ({name})") + print() + remote_id = input("Gib die remote Entity-ID ein: ").strip() + else: + print(f"Gefunden: {len(remotes)} Remotes") + for i, r in enumerate(remotes): + print(f" [{i+1}] {r['entity_id']} - {r['name']} ({r['state']})") + + if len(remotes) == 1: + remote_id = remotes[0]['entity_id'] + else: + choice = input("Waehle [1-{}]: ".format(len(remotes))).strip() + remote_id = remotes[int(choice)-1]['entity_id'] + + print() + print(f"Verwende: {media_player_id}") + print(f"Verwende: {remote_id}") + print() + + # Generiere Karte + card_yaml = generate_lovelace_card(media_player_id, remote_id) + + # Speichere Datei + output_file = "sony_tv_remote_FERTIG.yaml" + with open(output_file, 'w', encoding='utf-8') as f: + f.write(card_yaml) + + print("=" * 60) + print("FERTIG!") + print("=" * 60) + print() + print(f"Datei erstellt: {output_file}") + print() + print("So fuegst du die Karte hinzu:") + print("1. Oeffne Home Assistant Dashboard") + print("2. Klicke oben rechts auf die 3 Punkte -> 'Dashboard bearbeiten'") + print("3. Klicke auf '+ KARTE HINZUFUEGEN'") + print("4. Scrolle nach unten und waehle 'Manuell'") + print(f"5. Kopiere den Inhalt von '{output_file}' und fuege ihn ein") + print("6. Klicke 'SPEICHERN'") + print() + print("Oder kopiere diesen YAML-Code direkt:") + print("-" * 60) + print(card_yaml[:500] + "...") + print("-" * 60) + print(f"(Vollstaendiger Code in: {output_file})") + +if __name__ == "__main__": + main() From 568011162dc1a68fbfaddba12086891b3719932d Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 13 Dec 2025 15:21:03 +0000 Subject: [PATCH 3/3] Add corrected Sony TV remote card for media_player.kd_55s8005c_2 --- sony_tv_remote_KORRIGIERT.yaml | 431 +++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 sony_tv_remote_KORRIGIERT.yaml diff --git a/sony_tv_remote_KORRIGIERT.yaml b/sony_tv_remote_KORRIGIERT.yaml new file mode 100644 index 0000000..4ecb0d7 --- /dev/null +++ b/sony_tv_remote_KORRIGIERT.yaml @@ -0,0 +1,431 @@ +type: vertical-stack +cards: + - type: entities + title: "Sony Bravia TV" + entities: + - entity: media_player.kd_55s8005c_2 + name: "TV Status" + state_color: true + + - type: grid + columns: 3 + square: false + cards: + - type: button + name: "Power" + icon: mdi:power + tap_action: + action: call-service + service: media_player.turn_on + target: + entity_id: media_player.kd_55s8005c_2 + hold_action: + action: call-service + service: media_player.turn_off + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "Home" + icon: mdi:home + tap_action: + action: call-service + service: remote.send_command + data: + command: HOME + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "Input" + icon: mdi:import + tap_action: + action: call-service + service: remote.send_command + data: + command: INPUT + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "" + tap_action: + action: none + + - type: button + icon: mdi:chevron-up + tap_action: + action: call-service + service: remote.send_command + data: + command: UP + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 50px + + - type: button + name: "" + tap_action: + action: none + + - type: button + icon: mdi:chevron-left + tap_action: + action: call-service + service: remote.send_command + data: + command: LEFT + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 50px + + - type: button + name: "OK" + icon: mdi:checkbox-blank-circle + tap_action: + action: call-service + service: remote.send_command + data: + command: CONFIRM + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 50px + + - type: button + icon: mdi:chevron-right + tap_action: + action: call-service + service: remote.send_command + data: + command: RIGHT + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 50px + + - type: button + name: "" + tap_action: + action: none + + - type: button + icon: mdi:chevron-down + tap_action: + action: call-service + service: remote.send_command + data: + command: DOWN + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 50px + + - type: button + name: "" + tap_action: + action: none + + - type: button + name: "Zurueck" + icon: mdi:arrow-left + tap_action: + action: call-service + service: remote.send_command + data: + command: RETURN + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "Menu" + icon: mdi:menu + tap_action: + action: call-service + service: remote.send_command + data: + command: OPTIONS + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "Guide" + icon: mdi:television-guide + tap_action: + action: call-service + service: remote.send_command + data: + command: GUIDE + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: grid + columns: 4 + square: false + cards: + - type: button + name: "Vol+" + icon: mdi:volume-plus + tap_action: + action: call-service + service: media_player.volume_up + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "Vol-" + icon: mdi:volume-minus + tap_action: + action: call-service + service: media_player.volume_down + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "CH+" + icon: mdi:chevron-up-box + tap_action: + action: call-service + service: remote.send_command + data: + command: CHANNEL_UP + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "CH-" + icon: mdi:chevron-down-box + tap_action: + action: call-service + service: remote.send_command + data: + command: CHANNEL_DOWN + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 40px + + - type: button + name: "Mute" + icon: mdi:volume-mute + tap_action: + action: call-service + service: media_player.volume_mute + data: + is_volume_muted: true + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 40px + + - type: grid + columns: 5 + square: false + cards: + - type: button + icon: mdi:rewind + tap_action: + action: call-service + service: remote.send_command + data: + command: REWIND + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 35px + + - type: button + icon: mdi:play + tap_action: + action: call-service + service: media_player.media_play + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 35px + + - type: button + icon: mdi:pause + tap_action: + action: call-service + service: media_player.media_pause + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 35px + + - type: button + icon: mdi:stop + tap_action: + action: call-service + service: media_player.media_stop + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 35px + + - type: button + icon: mdi:fast-forward + tap_action: + action: call-service + service: remote.send_command + data: + command: FORWARD + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 35px + + - type: grid + columns: 4 + square: false + cards: + - type: button + name: "Netflix" + icon: mdi:netflix + tap_action: + action: call-service + service: remote.send_command + data: + command: NETFLIX + target: + entity_id: remote.kd_55s8005c_2 + icon_height: 35px + + - type: button + name: "YouTube" + icon: mdi:youtube + tap_action: + action: call-service + service: media_player.select_source + data: + source: "YouTube" + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 35px + + - type: button + name: "Prime" + icon: mdi:amazon + tap_action: + action: call-service + service: media_player.select_source + data: + source: "Prime Video" + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 35px + + - type: button + name: "Disney+" + icon: mdi:movie-open + tap_action: + action: call-service + service: media_player.select_source + data: + source: "Disney+" + target: + entity_id: media_player.kd_55s8005c_2 + icon_height: 35px + + - type: grid + columns: 3 + square: true + cards: + - type: button + name: "1" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_1 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "2" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_2 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "3" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_3 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "4" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_4 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "5" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_5 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "6" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_6 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "7" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_7 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "8" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_8 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "9" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_9 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "" + tap_action: + action: none + - type: button + name: "0" + tap_action: + action: call-service + service: remote.send_command + data: + command: NUM_0 + target: + entity_id: remote.kd_55s8005c_2 + - type: button + name: "" + tap_action: + action: none