diff --git a/.gitignore b/.gitignore index 881ad01b..1f477121 100755 --- a/.gitignore +++ b/.gitignore @@ -17,7 +17,6 @@ home-assistant_v2.db *.db-wal *.sqlite deps -hacs __pycache__ tts secrets.yaml @@ -31,3 +30,6 @@ nest.conf ipchange.yaml ip_bans.yaml production_auth.json +hacs +alexa_media +custom_components diff --git a/config/.HA_VERSION b/config/.HA_VERSION index d61b8368..d67b2506 100755 --- a/config/.HA_VERSION +++ b/config/.HA_VERSION @@ -1 +1 @@ -0.108.6 \ No newline at end of file +0.109.2 \ No newline at end of file diff --git a/config/automation/Timed_Triggers/startup_notification.yaml b/config/automation/Timed_Triggers/startup_notification.yaml index 4115d8bc..358353de 100755 --- a/config/automation/Timed_Triggers/startup_notification.yaml +++ b/config/automation/Timed_Triggers/startup_notification.yaml @@ -3,7 +3,7 @@ ################################### - alias: Startup Notification and Shut startup lights - + trigger: - platform: homeassistant event: start @@ -26,3 +26,14 @@ data: topic: "garadget/Garadget Large/command" payload: "get-status" + + - service: notify.alexa_media + data: + target: + - media_player.office + - media_player.kitchen + title: "Home Assistant Restarted" + data: + type: announce + #method: all + message: "Home Assistant has been restarted." diff --git a/config/custom_components/hacs/.translations/da.json b/config/custom_components/hacs/.translations/da.json index 8e45229e..95587993 100644 --- a/config/custom_components/hacs/.translations/da.json +++ b/config/custom_components/hacs/.translations/da.json @@ -12,6 +12,8 @@ "integration": "Integration", "integrations": "Integrationer", "manage": "administrer", + "netdaemon": "NetDaemon", + "netdaemon_apps": "NetDaemon-apps", "plugin": "Plugin", "plugins": "Plugins", "python_script": "Python-script", @@ -33,6 +35,7 @@ "user": { "data": { "appdaemon": "Aktiver opdagelse & sporing af AppDaemon-apps", + "netdaemon": "Aktiver opdagelse og sporing af NetDaemon-apps", "python_script": "Aktivér opdagelse og sporing af python_scripts", "sidepanel_icon": "Sidepanelikon", "sidepanel_title": "Sidepanelets titel", @@ -72,6 +75,7 @@ "country": "Filtrer med landekode.", "debug": "Aktiver debug.", "experimental": "Aktivér eksperimentelle funktioner", + "netdaemon": "Aktiver opdagelse og sporing af NetDaemon-apps", "not_in_use": "Ikke i brug med YAML", "release_limit": "Antal udgivelser, der skal vises.", "sidepanel_icon": "Sidepanelikon", @@ -113,6 +117,7 @@ "note_installed": "Når det er installeret, vil dette være placeret i", "note_integration": "du skal stadig føje den til filen 'configuration.yaml'", "note_plugin": "du skal stadig tilføje det til din lovelace-konfiguration ('ui-lovelace.yaml' eller Tekstbaseret redigering)", + "note_plugin_post_107": "du skal stadig tilføje det til din lovelace-konfiguration ('configuration.yaml' eller ressourceeditoren '\/config\/lovelace\/resources')", "open_issue": "Opret issue", "open_plugin": "Åbn plugin", "reinstall": "Geninstaller", diff --git a/config/custom_components/hacs/.translations/el.json b/config/custom_components/hacs/.translations/el.json index 0d446ada..f46eaa14 100644 --- a/config/custom_components/hacs/.translations/el.json +++ b/config/custom_components/hacs/.translations/el.json @@ -12,6 +12,7 @@ "installed": "εγκατεστημένο", "integration": "Ενσωμάτωση", "integrations": "Ενσωματωμένα", + "manage": "διαχειρίζονται", "netdaemon": "NetDaemon", "netdaemon_apps": "NetDaemon Apps", "plugin": "Πρόσθετο", @@ -76,6 +77,7 @@ "debug": "Ενεργοποίηση εντοπισμού σφαλμάτων.", "experimental": "Ενεργοποίση πειραματικών λειτουργιών", "netdaemon": "Ενεργοποίηση εύρεσης & παρακολούθησης για το NetDaemon", + "not_in_use": "Δεν χρησιμοποιείται με το YAML", "release_limit": "Αριθμός εκδόσεων που να παραθέτονται.", "sidepanel_icon": "Εικονίδιο πλαϊνού πάνελ", "sidepanel_title": "Τίτλος πλαϊνού πάνελ" @@ -100,6 +102,8 @@ "downloads": "Λήψεις", "flag_this": "Σημείωσε αυτό", "frontend_version": "Έκδοση Frontend", + "github_stars": "GitHub αστέρια", + "goto_integrations": "Μετάβαση στις ενσωματώσεις", "hide": "Απόκρυψη", "hide_beta": "Απόκριση του beta", "install": "Εγκατάσταση", @@ -124,6 +128,7 @@ }, "settings": { "add_custom_repository": "ΠΡΟΣΘΕΣΤΕ ΕΝΑ ΕΙΔΙΚΟ ΑΠΟΘΕΤΗΡΙΟ", + "adding_new_repo": "Προσθήκη νέου αποθετηρίου '{repo}'", "adding_new_repo_category": "Με κατηγορία '{category}'.", "category": "Κατηγορία", "compact_mode": "Συμπαγής λειτουργία", diff --git a/config/custom_components/hacs/.translations/es.json b/config/custom_components/hacs/.translations/es.json index ccc56f4a..b4a43665 100644 --- a/config/custom_components/hacs/.translations/es.json +++ b/config/custom_components/hacs/.translations/es.json @@ -63,10 +63,10 @@ "no": "No", "no_upgrades": "No hay actualizaciones pendientes", "ok": "OK", - "overwrite": "Si lo hace, se sobrescribirá.", + "overwrite": "Si haces esto, se sobrescribirá.", "reload_data": "Esto recarga los datos de todos los repositorios que HACS conoce, esto tardará algún tiempo en finalizar.", "restart_home_assistant": "¿Está seguro de que desea reiniciar Home Assistant?", - "uninstall": "¿Está seguro de que desea desinstalar '{item}'?", + "uninstall": "¿Está seguro de que deseas desinstalar '{item}'?", "upgrade_all": "Esto actualizará todos estos repositorios, asegúrese de que ha leído las notas de la versión de todos ellos antes de continuar.", "yes": "Si" }, @@ -117,9 +117,10 @@ "lovelace_no_js_type": "No se pudo determinar el tipo de plugin, revise el repositorio.", "newest": "más nuevo", "note_appdaemon": "deberá agregar esto a su archivo 'apps.yaml'", - "note_installed": "Al instalarse se encontrará en", + "note_installed": "Cuando esté instalado, se ubicará en", "note_integration": "deberá agregar esto a su archivo 'configuration.yaml'", "note_plugin": "deberá agregar esto a su configuración de lovelace ('ui-lovelace.yaml' o en el editor UI de lovelace)", + "note_plugin_post_107": "todavía necesita agregarlo a su configuración de lovelace ('configuration.yaml' o al editor de recursos '\/config\/lovelace\/resources')", "open_issue": "Abrir issue", "open_plugin": "Abrir plugin", "reinstall": "Reinstalar", @@ -148,7 +149,7 @@ "reload_data": "Recargar datos", "reload_window": "Recargar ventana", "repository_configuration": "Configuración del repositorio", - "save": "Grabar", + "save": "Guardar", "table": "Tabla", "table_view": "Vista de la tabla", "unhide": "mostrar", @@ -156,7 +157,7 @@ }, "store": { "ascending": "ascendente", - "clear_new": "Borrar todos los nuevos repositorios", + "clear_new": "Eliminar la lista los nuevos repositorios", "descending": "descendente", "last_updated": "Última actualización", "name": "Nombre", diff --git a/config/custom_components/hacs/.translations/fr.json b/config/custom_components/hacs/.translations/fr.json index 2d2f4875..c4c5d44b 100644 --- a/config/custom_components/hacs/.translations/fr.json +++ b/config/custom_components/hacs/.translations/fr.json @@ -120,6 +120,7 @@ "note_installed": "Une fois installé, il se trouvera dans", "note_integration": "Vous devez toujours l'ajouter à votre fichier 'configuration.yaml'", "note_plugin": "Vous devez toujours l'ajouter à votre configuration lovelace ('ui-lovelace.yaml' ou l'éditeur de configuration de l'interface)", + "note_plugin_post_107": "Vous devez toujours l'ajouter à votre configuration lovelace ('configuration.yaml' ou l'éditeur de configuration de l'interface '\/config\/lovelace\/resources')", "open_issue": "Ouvrir un ticket", "open_plugin": "Ouvrir le plugin", "reinstall": "Réinstaller", diff --git a/config/custom_components/hacs/.translations/hu.json b/config/custom_components/hacs/.translations/hu.json index 657e261c..a9db28e4 100644 --- a/config/custom_components/hacs/.translations/hu.json +++ b/config/custom_components/hacs/.translations/hu.json @@ -13,6 +13,8 @@ "integration": "Integráció", "integrations": "Integrációk", "manage": "kezelés", + "netdaemon": "NetDaemon", + "netdaemon_apps": "NetDaemon Appok", "plugin": "Bővítmény", "plugins": "Bővítmények", "python_script": "Python Szkript", @@ -34,6 +36,7 @@ "user": { "data": { "appdaemon": "AppDaemon appok felfedezésének és nyomon követésének engedélyezése", + "netdaemon": "NetDaemon appok felfedezésének és nyomon követésének engedélyezése", "python_script": "Python szkriptek felfedezésének és nyomon követésének engedélyezése", "sidepanel_icon": "Oldalsó panel ikon", "sidepanel_title": "Oldalsó panel cím", @@ -75,6 +78,7 @@ "country": "Szűrés országkóddal.", "debug": "Hibakeresés engedélyezése.", "experimental": "Kísérleti funkciók engedélyezése", + "netdaemon": "NetDaemon appok felfedezésének és nyomon követésének engedélyezése", "not_in_use": "YAML-lel nem használható", "release_limit": "Megjelenítendő kiadások száma.", "sidepanel_icon": "Oldalsó panel ikon", @@ -116,6 +120,7 @@ "note_installed": "Telepítéskor a következő helyre kerül:", "note_integration": "de még hozzá kell adnod a 'configuration.yaml' fájlhoz", "note_plugin": "de még hozzá kell adnod a lovelace konfigurációhoz (az 'ui-lovelace.yaml' fájlban vagy a Lovelace felületen a konfiguráció szerkesztőben)", + "note_plugin_post_107": "de még hozzá kell adnod a lovelace konfigurációhoz ('configuration.yaml' vagy az erőforrás szerkesztőben '\/config\/lovelace\/resources')", "open_issue": "Probléma jelentése", "open_plugin": "Bővítmény megnyitása", "reinstall": "Újratelepítés", diff --git a/config/custom_components/hacs/.translations/it.json b/config/custom_components/hacs/.translations/it.json index fc425296..c386ee87 100644 --- a/config/custom_components/hacs/.translations/it.json +++ b/config/custom_components/hacs/.translations/it.json @@ -120,6 +120,7 @@ "note_installed": "Una volta installato, si troverà in", "note_integration": "dovrai aggiungerlo nel file 'configuration.yaml'", "note_plugin": "devi aggiungere la configurazione nel file 'ui-lovelace.yaml' oppure via Editor RAW della UI.", + "note_plugin_post_107": "devi aggiungere la configurazione nel file 'ui-lovelace.yaml' oppure via Editor RAW della UI.", "open_issue": "Segnala anomalia", "open_plugin": "Apri plugin", "reinstall": "Reinstalla", diff --git a/config/custom_components/hacs/.translations/nb.json b/config/custom_components/hacs/.translations/nb.json index 0a7ef229..77840962 100644 --- a/config/custom_components/hacs/.translations/nb.json +++ b/config/custom_components/hacs/.translations/nb.json @@ -119,6 +119,7 @@ "note_installed": "Når det er installert, vil dette ligge i", "note_integration": "du må fortsatt legge den til 'configuration.yaml' filen", "note_plugin": "du må fortsatt legge den til i lovelace-konfigurasjonen ('ui-lovelace.yaml' eller den rå UI-konfigurasjonsredigereren)", + "note_plugin_post_107": "du må fortsatt legge den til i lovelace konfigurasjonen ('configuration.yaml' eller via resource behanleren i grensesnittet '\/config\/lovelace\/resources')", "open_issue": "Meld et problem", "open_plugin": "Åpne plugin", "reinstall": "Installer på nytt", diff --git a/config/custom_components/hacs/.translations/nl.json b/config/custom_components/hacs/.translations/nl.json index 5a8de78a..b092ce38 100644 --- a/config/custom_components/hacs/.translations/nl.json +++ b/config/custom_components/hacs/.translations/nl.json @@ -59,6 +59,7 @@ "exist": "{item} bestaat al.", "generic": "Weet je het zeker?", "home_assistant_is_restarting": "Een moment alstublieft, Home Assistant is aan het herstarten.", + "home_assistant_version_not_correct": "Je gebruikt Home Assistant versie '{haversion}', echter deze repository vereist dat minimaal versie '{minversion}' is geïnstalleerd.", "no": "Nee", "no_upgrades": "Geen upgrades in afwachting.", "ok": "Oké", @@ -119,6 +120,7 @@ "note_installed": "Wanneer geïnstalleerd, staat het in", "note_integration": "je moet het nog steeds toevoegen aan je 'configuration.yaml' bestand", "note_plugin": "je moet het nog steeds toevoegen aan je lovelace configuratie ('ui-lovelace.yaml') of raw UI config editor.", + "note_plugin_post_107": "je moet het nog steeds toevoegen aan je lovelace configuratie ('configuration.yaml' of de resource editor '\/config\/lovelace\/resources')", "open_issue": "Meld probleem", "open_plugin": "Open plugin", "reinstall": "Herinstalleer", diff --git a/config/custom_components/hacs/.translations/pl.json b/config/custom_components/hacs/.translations/pl.json index b76329d6..26e9c808 100644 --- a/config/custom_components/hacs/.translations/pl.json +++ b/config/custom_components/hacs/.translations/pl.json @@ -120,6 +120,7 @@ "note_installed": "Po zainstalowaniu dodatek będzie znajdować się w", "note_integration": "musisz jeszcze dodać integrację do pliku 'configuration.yaml'", "note_plugin": "musisz jeszcze dodać wtyczkę do konfiguracji interfejsu użytkownika (plik 'ui-lovelace.yaml' lub edytor interfejsu użytkownika)", + "note_plugin_post_107": "nadal musisz dodać go do konfiguracji Lovelace ('configuration.yaml' lub edytora zasobów '\/config\/lovelace\/resources')", "open_issue": "Powiadom o problemie", "open_plugin": "Otwórz dodatek", "reinstall": "Przeinstaluj", @@ -127,7 +128,7 @@ "restart_home_assistant": "Uruchom ponownie Home Assistant'a", "show_beta": "Wyświetl wydania beta", "uninstall": "Odinstaluj", - "update_information": "Informacje o aktualizacji", + "update_information": "Uaktualnij informacje", "upgrade": "Uaktualnij" }, "settings": { @@ -187,11 +188,11 @@ "second": "sekunda", "seconds": "sekundy", "x_days_ago": "{x} dni temu", - "x_hours_ago": "{x} godzin(-y) temu", - "x_minutes_ago": "{x} minut(-y) temu", - "x_months_ago": "{x} miesi(-ące\/-ęcy) temu", - "x_seconds_ago": "{x} sekund(-y) temu", - "x_years_ago": "{x} lat(-a) temu", + "x_hours_ago": "{x} godzin(y) temu", + "x_minutes_ago": "{x} minut(y) temu", + "x_months_ago": "{x} miesi(ące\/ęcy) temu", + "x_seconds_ago": "{x} sekund(y) temu", + "x_years_ago": "{x} lat(a) temu", "year": "rok", "years": "lata" } diff --git a/config/custom_components/hacs/.translations/pt-BR.json b/config/custom_components/hacs/.translations/pt-BR.json index e7089afc..0955f96e 100644 --- a/config/custom_components/hacs/.translations/pt-BR.json +++ b/config/custom_components/hacs/.translations/pt-BR.json @@ -4,6 +4,7 @@ "appdaemon": "AppDaemon", "appdaemon_apps": "AppDaemon Apps", "background_task": "Tarefa em segundo plano em execução, esta página será recarregada quando terminar.", + "check_log_file": "Verifique seu arquivo de log para obter mais detalhes.", "continue": "Continuar", "disabled": "Desativado", "documentation": "Documentação", @@ -49,13 +50,17 @@ "title": "HACS (Home Assistant Community Store)" }, "confirm": { + "add_to_lovelace": "Tem certeza de que deseja adicionar isso aos seus recursos do Lovelace?", "cancel": "Cancelar", "continue": "Tem certeza que quer continuar?", "delete": "Tem certeza de que deseja excluir '{item}'?", "exist": "{item} já existe", + "generic": "Tem certeza?", "home_assistant_is_restarting": "Espere, o Home Assistant está agora a reiniciar.", "no": "Não", + "no_upgrades": "Não há atualizações pendentes", "ok": "OK", + "overwrite": "Fazer isso irá substituí-lo.", "restart_home_assistant": "Tem certeza de que deseja reiniciar o Home Assistant?", "uninstall": "Tem certeza de que deseja desinstalar '{item}'?", "yes": "Sim" @@ -80,6 +85,7 @@ "integration_not_loaded": "Esta integração não é carregada no Home Assistant.", "no_restart_required": "Não é necessário reiniciar", "not_loaded": "Não carregado", + "plugin_not_loaded": "Este plugin não foi adicionado aos seus recursos do Lovelace.", "restart": "Você precisa reiniciar o Home Assistant.", "restart_pending": "Reiniciar pendente" }, diff --git a/config/custom_components/hacs/.translations/ro.json b/config/custom_components/hacs/.translations/ro.json index d6884aa5..2c4e1263 100644 --- a/config/custom_components/hacs/.translations/ro.json +++ b/config/custom_components/hacs/.translations/ro.json @@ -4,6 +4,7 @@ "appdaemon": "AppDaemon", "appdaemon_apps": "Aplicații AppDaemon", "background_task": "Activitatea de fundal se execută, această pagină se va reîncărca atunci când este gata.", + "check_log_file": "Verificați log-ul pentru mai multe detalii.", "continue": "Continua", "disabled": "Dezactivat", "documentation": "Documentație", @@ -11,6 +12,7 @@ "installed": "instalat", "integration": "Integrare", "integrations": "Integrări", + "manage": "administra", "netdaemon": "NetDaemon", "netdaemon_apps": "Aplicații NetDaemon", "plugin": "Plugin", @@ -48,12 +50,19 @@ "title": "HACS (Home Assistant Community Store)" }, "confirm": { + "add_to_lovelace": "Ești sigur că vrei să adaugi asta la resursele tale Lovelace?", "bg_task": "Acțiunea este dezactivată în timp ce activitățile de fundal se execută.", "cancel": "Anulare", + "continue": "Esti sigur ca vrei sa continui?", "delete": "Sigur doriți să ștergeți '{item}'?", "exist": "{item} există deja", + "generic": "Ești sigur?", + "home_assistant_is_restarting": "Asteptati, Home Assistant repornește.", "no": "Nu", + "no_upgrades": "Nu există actualizări în curs", "ok": "OK", + "overwrite": "Făcând acest lucru, îl va suprascrie.", + "restart_home_assistant": "Sigur doriți să reporniți Home Assistant?", "uninstall": "Sigur doriți să dezinstalați '{item}'?", "yes": "Da" }, @@ -63,6 +72,7 @@ "data": { "appdaemon": "Activați descoperirea și urmărirea aplicațiilor AppDaemon", "country": "Filtrează cu codul țării.", + "debug": "Activează depanarea.", "experimental": "Activați funcțiile experimentale", "netdaemon": "Activați descoperirea și urmărirea aplicațiilor NetDaemon", "not_in_use": "Nu este utilizat cu YAML", @@ -76,6 +86,8 @@ "repository_banner": { "integration_not_loaded": "Această integrare nu este încărcată în Home Assistant.", "no_restart_required": "Nu este necesară repornirea", + "not_loaded": "Neîncărcat", + "plugin_not_loaded": "Acest plugin nu este adăugat la resursele Lovelace.", "restart": "Trebuie să reporniți Home Assistant.", "restart_pending": "Reporniți în așteptare" }, @@ -89,6 +101,7 @@ "flag_this": "Semnalizează", "frontend_version": "Versiune frontend", "github_stars": "Stele GitHub", + "goto_integrations": "Mergi la integrări", "hide": "Ascunde", "hide_beta": "Ascundere beta", "install": "Instalează", @@ -136,10 +149,12 @@ }, "store": { "ascending": "ascendent", + "clear_new": "Ștergeți toate depozitele noi", "descending": "descendent", "last_updated": "Ultima actualizare", "name": "Nume", "new_repositories": "Noi depozite", + "pending_upgrades": "Actualizări în așteptare", "placeholder_search": "Vă rugăm să introduceți un termen de căutare ...", "sort": "fel", "stars": "Stele", diff --git a/config/custom_components/hacs/.translations/ru.json b/config/custom_components/hacs/.translations/ru.json index 7cde0bf4..117df45a 100644 --- a/config/custom_components/hacs/.translations/ru.json +++ b/config/custom_components/hacs/.translations/ru.json @@ -58,6 +58,7 @@ "delete_installed": "'{item}' установлен, вам нужно нажать 'Удалить', чтобы удалить его.", "exist": "{item} уже существует.", "generic": "Вы уверены?", + "home_assistant_is_restarting": "Подожди, теперь Home Assistant перезагружается.", "no": "Нет", "no_upgrades": "Нет обновлений", "ok": "ОК", diff --git a/config/custom_components/hacs/.translations/sl.json b/config/custom_components/hacs/.translations/sl.json index ada106e5..5f3283d9 100644 --- a/config/custom_components/hacs/.translations/sl.json +++ b/config/custom_components/hacs/.translations/sl.json @@ -120,6 +120,7 @@ "note_installed": "Ko bo nameščen, se bo nahajal v", "note_integration": "Še vedno ga morate dodati v svojo 'configuration.yaml' datoteko", "note_plugin": "vendar ga še vedno morate dodati v svojo lovelace konfiguracijo ('ui-lovelace.yaml' ali \"raw\" UI config urejevalnik)", + "note_plugin_post_107": "še vedno ga morate dodati v svojo konfiguracijo lovelace ('config.yaml' ali urejevalnik virov '\/config\/lovelace\/resources')", "open_issue": "Odprite težavo", "open_plugin": "Odprite vtičnik", "reinstall": "Znova namestite", diff --git a/config/custom_components/hacs/.translations/sv.json b/config/custom_components/hacs/.translations/sv.json index e08e9a70..3d84d5cf 100644 --- a/config/custom_components/hacs/.translations/sv.json +++ b/config/custom_components/hacs/.translations/sv.json @@ -4,6 +4,7 @@ "appdaemon": "AppDaemon", "appdaemon_apps": "Appdaemon Applikationer", "background_task": "Bakgrundsjobb körs, denna sida kommer att laddas igen när det är klart.", + "check_log_file": "Kontrollera din loggfil för mer information.", "continue": "Fortsätta", "disabled": "Inaktiverad", "documentation": "Dokumentation", @@ -11,6 +12,7 @@ "installed": "installerad", "integration": "Integration", "integrations": "Integrationer", + "manage": "hantera", "netdaemon": "NetDaemon", "netdaemon_apps": "NetDaemon Applikationer", "plugin": "Plugin", @@ -56,10 +58,13 @@ "delete_installed": "'{item}' är installerat, du måste avinstallera det innan du kan ta bort det.", "exist": "{item} existerar redan", "generic": "Är du säker?", + "home_assistant_is_restarting": "Vänta, Home Assistant startar nu om.", + "home_assistant_version_not_correct": "Du kör Home Assistant-versionen '{haversion}', men detta repository kräver att lägsta versionen '{minversion}' måste installeras.", "no": "Nej", "no_upgrades": "Inga uppgraderingar väntar", "ok": "OK", "overwrite": "Detta kommer att skriva över den.", + "reload_data": "Detta laddar om data för alla repositories HACS vet om, kommer detta att ta lite tid att slutföra.", "restart_home_assistant": "Är du säker på att du vill starta om Home Assistant?", "uninstall": "Är du säker på att du vill avinstallera '{item}'?", "upgrade_all": "Detta kommer uppgradera alla dessa repositories, säkerhetsställ att du läst release anteckningarna för dem alla innan du fortsätter", @@ -74,6 +79,7 @@ "debug": "Aktivera felsökning", "experimental": "Använd experimentella funktioner", "netdaemon": "Upptäck och följ NetDaemon applikationer", + "not_in_use": "Används inte med YAML", "release_limit": "Antalet releaser som visas.", "sidepanel_icon": "Ikon för sidpanel", "sidepanel_title": "Rubrik för sidpanel" @@ -82,6 +88,8 @@ } }, "repository_banner": { + "config_flow": "Den här integreringen stöder config_flow, det innebär att du nu kan gå till integrationsdelen i användargränssnittet för att konfigurera det.", + "config_flow_title": "UI-konfiguration stöds", "integration_not_loaded": "Denna integration inte laddats i Hem Assistent.", "no_restart_required": "Ingen omstart krävs", "not_loaded": "Ej laddad", @@ -112,6 +120,7 @@ "note_installed": "När den är installerad kommer den finnas i", "note_integration": "du behöver fortfarande lägga den till filen 'configuration.yaml'", "note_plugin": "du behöver fortfarande lägga till den till din lovelace konfiguration ('ui-lovelace.yaml' eller raw UI config redigerare)", + "note_plugin_post_107": "du behöver fortfarande lägga till den i din lovelace-konfiguration ('configuration.yaml' eller resursredigeraren \/config\/lovelace\/resources')", "open_issue": "Rapportera problem", "open_plugin": "Öppna plugin", "reinstall": "Ominstallera", @@ -139,6 +148,7 @@ "open_repository": "Öppna Repository", "reload_data": "Ladda om data", "reload_window": "Ladda om fönstret", + "repository_configuration": "Konfiguration av repository", "save": "Spara", "table": "Tabell", "table_view": "Tabellvy", @@ -148,6 +158,7 @@ "store": { "ascending": "stigande", "clear_new": "Rensa alla nya förvar", + "descending": "fallande", "last_updated": "Senast uppdaterad", "name": "Namn", "new_repositories": "Nya förvar", diff --git a/config/custom_components/hacs/.translations/zh-Hans.json b/config/custom_components/hacs/.translations/zh-Hans.json index 73ecd24c..415a3974 100644 --- a/config/custom_components/hacs/.translations/zh-Hans.json +++ b/config/custom_components/hacs/.translations/zh-Hans.json @@ -66,7 +66,7 @@ "overwrite": "这样做会覆盖它。", "reload_data": "这将重新加载HACS知道的所有仓库的数据,这需要一些时间才能完成。", "restart_home_assistant": "您确定要重新启动Home Assistant吗?", - "uninstall": "您确定要卸载“ {item} ”吗?", + "uninstall": "您确定要卸载 '{item}' 吗?", "upgrade_all": "这将升级所有这些仓库,请确保在继续之前已阅读所有仓库的发行说明。", "yes": "确定" }, @@ -120,6 +120,7 @@ "note_installed": "安装后,它将位于", "note_integration": "您仍然需要将其添加到“ configuration.yaml”文件中", "note_plugin": "您仍然需要将其添加到lovelace配置中(“ ui-lovelace.yaml”或原始配置编辑器)ui-lovelace.yaml", + "note_plugin_post_107": "您仍然需要将其添加到lovelace配置中(“ configuration.yaml”或资源编辑器“\/config\/lovelace\/resources”)", "open_issue": "提交问题", "open_plugin": "打开插件", "reinstall": "重新安装", diff --git a/config/custom_components/hacs/__init__.py b/config/custom_components/hacs/__init__.py index e4779497..2f212e1b 100644 --- a/config/custom_components/hacs/__init__.py +++ b/config/custom_components/hacs/__init__.py @@ -6,7 +6,7 @@ https://hacs.xyz/ """ import voluptuous as vol -from aiogithubapi import AIOGitHub +from aiogithubapi import AIOGitHub, AIOGitHubException from homeassistant import config_entries from homeassistant.const import EVENT_HOMEASSISTANT_START from homeassistant.const import __version__ as HAVERSION @@ -21,6 +21,7 @@ from custom_components.hacs.configuration_schema import ( ) from custom_components.hacs.const import DOMAIN, ELEMENT_TYPES, STARTUP, VERSION from custom_components.hacs.constrains import check_constans, check_requirements +from custom_components.hacs.helpers.remaining_github_calls import get_fetch_updates_for from custom_components.hacs.hacsbase.configuration import Configuration from custom_components.hacs.hacsbase.data import HacsData from custom_components.hacs.setup import ( @@ -43,6 +44,8 @@ async def async_setup(hass, config): hacs = get_hacs() if DOMAIN not in config: return True + if hacs.configuration and hacs.configuration.config_type == "flow": + return True hass.data[DOMAIN] = config hacs.hass = hass hacs.session = async_create_clientsession(hass) @@ -78,7 +81,10 @@ async def async_setup_entry(hass, config_entry): hacs.configuration.config_type = "flow" hacs.configuration.config_entry = config_entry config_entry.add_update_listener(reload_hacs) - startup_result = await hacs_startup() + try: + startup_result = await hacs_startup() + except AIOGitHubException: + startup_result = False if not startup_result: hacs.system.disabled = True raise ConfigEntryNotReady @@ -89,7 +95,10 @@ async def async_setup_entry(hass, config_entry): async def startup_wrapper_for_yaml(): """Startup wrapper for yaml config.""" hacs = get_hacs() - startup_result = await hacs_startup() + try: + startup_result = await hacs_startup() + except AIOGitHubException: + startup_result = False if not startup_result: hacs.system.disabled = True hacs.hass.components.frontend.async_remove_panel( @@ -113,6 +122,12 @@ async def hacs_startup(): await hacs.hass.services.async_call( "logger", "set_level", {"hacs": "debug"} ) + await hacs.hass.services.async_call( + "logger", "set_level", {"queueman": "debug"} + ) + await hacs.hass.services.async_call( + "logger", "set_level", {"AioGitHub": "debug"} + ) except ServiceNotFound: hacs.logger.error( "Could not set logging level to debug, logger is not enabled" @@ -132,6 +147,12 @@ async def hacs_startup(): ) hacs.data = HacsData() + can_update = await get_fetch_updates_for(hacs.github) + if can_update == 0: + hacs.logger.info("HACS is ratelimited, repository updates will resume in 1h.") + else: + hacs.logger.debug(f"Can update {can_update} repositories") + # Check HACS Constrains if not await hacs.hass.async_add_executor_job(check_constans): if hacs.configuration.config_type == "flow": diff --git a/config/custom_components/hacs/const.py b/config/custom_components/hacs/const.py index 714a859a..1eee1354 100644 --- a/config/custom_components/hacs/const.py +++ b/config/custom_components/hacs/const.py @@ -1,7 +1,7 @@ """Constants for HACS""" NAME_LONG = "HACS (Home Assistant Community Store)" NAME_SHORT = "HACS" -VERSION = "0.23.2" +VERSION = "0.24.3" DOMAIN = "hacs" PROJECT_URL = "https://github.com/hacs/integration/" CUSTOM_UPDATER_LOCATIONS = [ diff --git a/config/custom_components/hacs/hacsbase/__init__.py b/config/custom_components/hacs/hacsbase/__init__.py index 70c82daa..3cd59e44 100644 --- a/config/custom_components/hacs/hacsbase/__init__.py +++ b/config/custom_components/hacs/hacsbase/__init__.py @@ -8,6 +8,7 @@ from homeassistant.helpers.event import async_call_later, async_track_time_inter from aiogithubapi import AIOGitHubException, AIOGitHubRatelimit from integrationhelper import Logger +from queueman import QueueManager from custom_components.hacs.hacsbase.task_factory import HacsTaskFactory from custom_components.hacs.hacsbase.exceptions import HacsException @@ -21,6 +22,7 @@ from custom_components.hacs.helpers.get_defaults import ( ) from custom_components.hacs.helpers.register_repository import register_repository +from custom_components.hacs.helpers.remaining_github_calls import get_fetch_updates_for from custom_components.hacs.globals import removed_repositories, get_removed, is_removed from custom_components.hacs.repositories.removed import RemovedRepository @@ -83,6 +85,7 @@ class Hacs: """The base class of HACS, nested thoughout the project.""" token = f"{str(uuid.uuid4())}-{str(uuid.uuid4())}" + action = False hacsweb = f"/hacsweb/{token}" hacsapi = f"/hacsapi/{token}" repositories = [] @@ -98,6 +101,7 @@ class Hacs: version = None session = None factory = HacsTaskFactory() + queue = QueueManager() system = System() recuring_tasks = [] common = HacsCommon() @@ -170,10 +174,17 @@ class Hacs: self.hass, self.recuring_tasks_all, timedelta(minutes=800) ) ) + self.recuring_tasks.append( + async_track_time_interval( + self.hass, self.prosess_queue, timedelta(minutes=10) + ) + ) self.hass.bus.async_fire("hacs/reload", {"force": True}) await self.recuring_tasks_installed() + await self.prosess_queue() + self.system.status.startup = False self.system.status.new = False self.system.status.background_task = False @@ -251,6 +262,27 @@ class Hacs: self.logger.critical("Resarting Home Assistant") self.hass.async_create_task(self.hass.async_stop(100)) + async def prosess_queue(self, notarealarg=None): + """Recuring tasks for installed repositories.""" + if not self.queue.has_pending_tasks: + self.logger.debug("Nothing in the queue") + return + if self.queue.running: + self.logger.debug("Queue is already running") + return + + can_update = await get_fetch_updates_for(self.github) + if can_update == 0: + self.logger.info( + "HACS is ratelimited, repository updates will resume later." + ) + else: + self.system.status.background_task = True + self.hass.bus.async_fire("hacs/status", {}) + await self.queue.execute(can_update) + self.system.status.background_task = False + self.hass.bus.async_fire("hacs/status", {}) + async def recuring_tasks_installed(self, notarealarg=None): """Recuring tasks for installed repositories.""" self.logger.debug( @@ -265,9 +297,8 @@ class Hacs: repository.status.installed and repository.data.category in self.common.categories ): - self.factory.tasks.append(self.factory.safe_update(repository)) + self.queue.add(self.factory.safe_update(repository)) - await self.factory.execute() await self.handle_critical_repositories() self.system.status.background_task = False self.hass.bus.async_fire("hacs/status", {}) @@ -284,9 +315,8 @@ class Hacs: self.logger.debug(self.github.ratelimits.reset_utc) for repository in self.repositories: if repository.data.category in self.common.categories: - self.factory.tasks.append(self.factory.safe_common_update(repository)) + self.queue.add(self.factory.safe_common_update(repository)) - await self.factory.execute() await self.load_known_repositories() await self.clear_out_removed_repositories() self.system.status.background_task = False @@ -350,6 +380,4 @@ class Hacs: continue if self.is_known(repo): continue - self.factory.tasks.append(self.factory.safe_register(repo, category)) - await self.factory.execute() - self.logger.info("Loading known repositories finished") + self.queue.add(self.factory.safe_register(repo, category)) diff --git a/config/custom_components/hacs/hacsbase/data.py b/config/custom_components/hacs/hacsbase/data.py index ca3ed838..8590aa16 100644 --- a/config/custom_components/hacs/hacsbase/data.py +++ b/config/custom_components/hacs/hacsbase/data.py @@ -5,7 +5,7 @@ from ..repositories.repository import HacsRepository from ..repositories.manifest import HacsManifest from ..store import async_save_to_store, async_load_from_store -from custom_components.hacs.globals import get_hacs, removed_repositories, get_removed +from custom_components.hacs.globals import get_hacs from custom_components.hacs.helpers.register_repository import register_repository @@ -35,10 +35,6 @@ class HacsData: }, ) - await async_save_to_store( - self.hacs.hass, "removed", [x.__dict__ for x in removed_repositories] - ) - # Repositories content = {} for repository in self.hacs.repositories: @@ -77,7 +73,6 @@ class HacsData: """Restore saved data.""" hacs = await async_load_from_store(self.hacs.hass, "hacs") repositories = await async_load_from_store(self.hacs.hass, "repositories") - removed = await async_load_from_store(self.hacs.hass, "removed") try: if not hacs and not repositories: # Assume new install @@ -90,10 +85,6 @@ class HacsData: self.hacs.configuration.frontend_compact = hacs.get("compact", False) self.hacs.configuration.onboarding_done = hacs.get("onboarding_done", False) - for entry in removed: - removed_repo = get_removed(entry["repository"]) - removed_repo.update_data(entry) - # Repositories for entry in repositories: repo = repositories[entry] diff --git a/config/custom_components/hacs/helpers/download.py b/config/custom_components/hacs/helpers/download.py index 20414db6..17818f9b 100644 --- a/config/custom_components/hacs/helpers/download.py +++ b/config/custom_components/hacs/helpers/download.py @@ -1,7 +1,9 @@ """Helpers to download repository content.""" +import os import pathlib import tempfile import zipfile +from queueman import QueueManager, concurrent from custom_components.hacs.hacsbase.exceptions import HacsException from custom_components.hacs.handler.download import async_download_file, async_save_file from custom_components.hacs.helpers.filters import filter_content_return_one_of_type @@ -123,6 +125,8 @@ async def download_zip(repository, validate): ) as zip_file: zip_file.extractall(repository.content.path.local) + os.remove(f"{tempfile.gettempdir()}/{repository.data.filename}") + if result: repository.logger.info(f"download of {content.name} complete") continue @@ -135,6 +139,7 @@ async def download_zip(repository, validate): async def download_content(repository): """Download the content of a directory.""" + queue = QueueManager() contents = gather_files_to_download(repository) repository.logger.debug(repository.data.filename) if not contents: @@ -144,38 +149,44 @@ async def download_content(repository): if repository.data.content_in_root and repository.data.filename: if content.name != repository.data.filename: continue - repository.logger.debug(f"Downloading {content.name}") + queue.add(dowload_repository_content(repository, content)) + await queue.execute() - filecontent = await async_download_file(content.download_url) - if filecontent is None: - repository.validate.errors.append(f"[{content.name}] was not downloaded.") - continue +@concurrent(10) +async def dowload_repository_content(repository, content): + """Download content.""" + repository.logger.debug(f"Downloading {content.name}") - # Save the content of the file. - if repository.content.single or content.path is None: - local_directory = repository.content.path.local + filecontent = await async_download_file(content.download_url) - else: - _content_path = content.path - if not repository.data.content_in_root: - _content_path = _content_path.replace( - f"{repository.content.path.remote}", "" - ) - - local_directory = f"{repository.content.path.local}/{_content_path}" - local_directory = local_directory.split("/") - del local_directory[-1] - local_directory = "/".join(local_directory) - - # Check local directory - pathlib.Path(local_directory).mkdir(parents=True, exist_ok=True) - - local_file_path = (f"{local_directory}/{content.name}").replace("//", "/") - - result = await async_save_file(local_file_path, filecontent) - if result: - repository.logger.info(f"download of {content.name} complete") - continue + if filecontent is None: repository.validate.errors.append(f"[{content.name}] was not downloaded.") + return + # Save the content of the file. + if repository.content.single or content.path is None: + local_directory = repository.content.path.local + + else: + _content_path = content.path + if not repository.data.content_in_root: + _content_path = _content_path.replace( + f"{repository.content.path.remote}", "" + ) + + local_directory = f"{repository.content.path.local}/{_content_path}" + local_directory = local_directory.split("/") + del local_directory[-1] + local_directory = "/".join(local_directory) + + # Check local directory + pathlib.Path(local_directory).mkdir(parents=True, exist_ok=True) + + local_file_path = (f"{local_directory}/{content.name}").replace("//", "/") + + result = await async_save_file(local_file_path, filecontent) + if result: + repository.logger.info(f"download of {content.name} complete") + return + repository.validate.errors.append(f"[{content.name}] was not downloaded.") diff --git a/config/custom_components/hacs/helpers/information.py b/config/custom_components/hacs/helpers/information.py index 2fde31fa..5a33b4a8 100644 --- a/config/custom_components/hacs/helpers/information.py +++ b/config/custom_components/hacs/helpers/information.py @@ -30,7 +30,9 @@ async def get_info_md_content(repository): info = info.content.replace("= "107": logger = Logger("hacs.deprecated") logger.warning( - "The '/community_plugin/*' is deprecated and will be removed in an upcomming version of HACS, it has been replaced by '/hacsfiles/*', if you use the UI to manage your lovelace configuration, you can update this by going to the settings tab in HACS, if you use YAML to manage your lovelace configuration, you manually need to replace the URL in your resources." + "The '/community_plugin/*' is deprecated and will be removed in an upcoming version of HACS, it has been replaced by '/hacsfiles/*', if you use the UI to manage your lovelace configuration, you can update this by going to the settings tab in HACS, if you use YAML to manage your lovelace configuration, you manually need to replace the URL in your resources." ) return await get_file_response(requested_file) diff --git a/config/custom_components/hacs/iconset.js b/config/custom_components/hacs/iconset.js index ab225c75..5af5a3cc 100644 --- a/config/custom_components/hacs/iconset.js +++ b/config/custom_components/hacs/iconset.js @@ -1,6 +1,7 @@ const iconset = document.createElement("ha-iconset-svg"); iconset.name = "hacs"; iconset.size = "1024"; +iconset.style = "display: hidden;" iconset.innerHTML = ` diff --git a/config/custom_components/hacs/manifest.json b/config/custom_components/hacs/manifest.json index 95c49e0a..fe931bc6 100644 --- a/config/custom_components/hacs/manifest.json +++ b/config/custom_components/hacs/manifest.json @@ -11,14 +11,14 @@ ], "documentation": "https://hacs.xyz/docs/configuration/start", "domain": "hacs", - "issues": "https://hacs.xyz/docs/issues", "name": "HACS (Home Assistant Community Store)", "requirements": [ - "aiofiles==0.4.0", + "aiofiles==0.5.0", "aiogithubapi==0.5.0", "backoff==1.10.0", - "hacs_frontend==20200309184730", + "hacs_frontend==20200426112021", "integrationhelper==0.2.2", - "semantic_version==2.8.4" + "semantic_version==2.8.4", + "queueman==0.5" ] } \ No newline at end of file diff --git a/config/custom_components/hacs/repositories/appdaemon.py b/config/custom_components/hacs/repositories/appdaemon.py index 8dcf6b37..750ad464 100644 --- a/config/custom_components/hacs/repositories/appdaemon.py +++ b/config/custom_components/hacs/repositories/appdaemon.py @@ -50,8 +50,11 @@ class HacsAppdaemon(HacsRepository): self.logger.error(error) return self.validate.success - async def registration(self): + async def registration(self, ref=None): """Registration.""" + if ref is not None: + self.ref = ref + self.force_branch = True if not await self.validate_repository(): return False diff --git a/config/custom_components/hacs/repositories/integration.py b/config/custom_components/hacs/repositories/integration.py index c512d360..86406ab2 100644 --- a/config/custom_components/hacs/repositories/integration.py +++ b/config/custom_components/hacs/repositories/integration.py @@ -45,6 +45,8 @@ class HacsIntegration(HacsRepository): try: await get_integration_manifest(self) except HacsException as exception: + if self.hacs.action: + raise HacsException(exception) self.logger.error(exception) # Handle potential errors @@ -54,8 +56,11 @@ class HacsIntegration(HacsRepository): self.logger.error(error) return self.validate.success - async def registration(self): + async def registration(self, ref=None): """Registration.""" + if ref is not None: + self.ref = ref + self.force_branch = True if not await self.validate_repository(): return False diff --git a/config/custom_components/hacs/repositories/netdaemon.py b/config/custom_components/hacs/repositories/netdaemon.py index bfa50471..d9b14a22 100644 --- a/config/custom_components/hacs/repositories/netdaemon.py +++ b/config/custom_components/hacs/repositories/netdaemon.py @@ -58,8 +58,11 @@ class HacsNetdaemon(HacsRepository): self.logger.error(error) return self.validate.success - async def registration(self): + async def registration(self, ref=None): """Registration.""" + if ref is not None: + self.ref = ref + self.force_branch = True if not await self.validate_repository(): return False diff --git a/config/custom_components/hacs/repositories/plugin.py b/config/custom_components/hacs/repositories/plugin.py index 9c07c912..50f0eb3c 100644 --- a/config/custom_components/hacs/repositories/plugin.py +++ b/config/custom_components/hacs/repositories/plugin.py @@ -46,8 +46,11 @@ class HacsPlugin(HacsRepository): self.logger.error(error) return self.validate.success - async def registration(self): + async def registration(self, ref=None): """Registration.""" + if ref is not None: + self.ref = ref + self.force_branch = True if not await self.validate_repository(): return False diff --git a/config/custom_components/hacs/repositories/python_script.py b/config/custom_components/hacs/repositories/python_script.py index 067c4993..6defbf7e 100644 --- a/config/custom_components/hacs/repositories/python_script.py +++ b/config/custom_components/hacs/repositories/python_script.py @@ -39,7 +39,7 @@ class HacsPythonScript(HacsRepository): break if not compliant: raise HacsException( - f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant" + f"Repository structure for {self.ref.replace('tags/','')} is not compliant" ) # Handle potential errors @@ -49,8 +49,11 @@ class HacsPythonScript(HacsRepository): self.logger.error(error) return self.validate.success - async def registration(self): + async def registration(self, ref=None): """Registration.""" + if ref is not None: + self.ref = ref + self.force_branch = True if not await self.validate_repository(): return False @@ -80,7 +83,7 @@ class HacsPythonScript(HacsRepository): break if not compliant: raise HacsException( - f"Repostitory structure for {self.ref.replace('tags/','')} is not compliant" + f"Repository structure for {self.ref.replace('tags/','')} is not compliant" ) # Update name diff --git a/config/custom_components/hacs/repositories/repository.py b/config/custom_components/hacs/repositories/repository.py index c494b8a2..69ff7b4f 100644 --- a/config/custom_components/hacs/repositories/repository.py +++ b/config/custom_components/hacs/repositories/repository.py @@ -12,6 +12,7 @@ from ..handler.download import async_download_file, async_save_file from ..helpers.misc import version_left_higher_then_right from ..helpers.install import install_repository, version_to_install +from custom_components.hacs.hacsbase.exceptions import HacsException from custom_components.hacs.globals import get_hacs from custom_components.hacs.helpers.information import ( get_info_md_content, @@ -109,6 +110,7 @@ class HacsRepository: self.repository_object = None self.status = RepositoryStatus() self.state = None + self.force_branch = False self.integration_manifest = {} self.repository_manifest = HacsManifest.from_dict({}) self.validate = Validate() @@ -122,6 +124,8 @@ class HacsRepository: @property def pending_upgrade(self): """Return pending upgrade.""" + if not self.can_install: + return False if self.status.installed: if self.status.selected_tag is not None: if self.status.selected_tag == self.data.default_branch: @@ -272,6 +276,10 @@ class HacsRepository: # Set description self.data.description = self.data.description + if self.hacs.action: + if self.data.description is None or len(self.data.description) == 0: + raise HacsException("Missing repository description") + async def common_update(self): """Common information update steps of the repository.""" self.logger.debug("Getting repository information") @@ -345,7 +353,12 @@ class HacsRepository: async def get_repository_manifest_content(self): """Get the content of the hacs.json file.""" if not "hacs.json" in [x.filename for x in self.tree]: + if self.hacs.action: + raise HacsException("No hacs.json file in the root of the repository.") return + if self.hacs.action: + self.logger.debug("Found hacs.json") + if self.ref is None: self.ref = version_to_install(self) try: @@ -354,8 +367,11 @@ class HacsRepository: json.loads(manifest.content) ) self.data.update_data(json.loads(manifest.content)) - except (AIOGitHubException, Exception): # Gotta Catch 'Em All - pass + except (AIOGitHubException, Exception) as exception: # Gotta Catch 'Em All + if self.hacs.action: + raise HacsException(f"hacs.json file is not valid ({exception}).") + if self.hacs.action: + self.logger.debug("hacs.json is valid") def remove(self): """Run remove tasks.""" @@ -370,7 +386,8 @@ class HacsRepository: async def uninstall(self): """Run uninstall tasks.""" self.logger.info("Uninstalling") - await self.remove_local_directory() + if not await self.remove_local_directory(): + raise HacsException("Could not uninstall") self.status.installed = False if self.data.category == "integration": if self.config_flow: @@ -402,16 +419,25 @@ class HacsRepository: if self.data.category == "python_script": local_path = "{}/{}.py".format(self.content.path.local, self.data.name) elif self.data.category == "theme": - local_path = "{}/{}.yaml".format( - self.content.path.local, self.data.name - ) + if os.path.exists( + f"{self.hacs.system.config_path}/{self.hacs.configuration.theme_path}/{self.data.name}.yaml" + ): + os.remove( + f"{self.hacs.system.config_path}/{self.hacs.configuration.theme_path}/{self.data.name}.yaml" + ) + local_path = self.content.path.local + elif self.data.category == "integration": + if not self.data.domain: + self.logger.error("Missing domain") + return False + local_path = self.content.path.local else: local_path = self.content.path.local if os.path.exists(local_path): self.logger.debug(f"Removing {local_path}") - if self.data.category in ["python_script", "theme"]: + if self.data.category in ["python_script"]: os.remove(local_path) else: shutil.rmtree(local_path) @@ -421,4 +447,5 @@ class HacsRepository: except Exception as exception: self.logger.debug(f"Removing {local_path} failed with {exception}") - return + return False + return True diff --git a/config/custom_components/hacs/repositories/theme.py b/config/custom_components/hacs/repositories/theme.py index 584e27be..63f91ae7 100644 --- a/config/custom_components/hacs/repositories/theme.py +++ b/config/custom_components/hacs/repositories/theme.py @@ -44,8 +44,11 @@ class HacsTheme(HacsRepository): self.logger.error(error) return self.validate.success - async def registration(self): + async def registration(self, ref=None): """Registration.""" + if ref is not None: + self.ref = ref + self.force_branch = True if not await self.validate_repository(): return False diff --git a/config/custom_components/hacs/ws_api_handlers.py b/config/custom_components/hacs/ws_api_handlers.py index dbf2d2f4..b01ceb3a 100644 --- a/config/custom_components/hacs/ws_api_handlers.py +++ b/config/custom_components/hacs/ws_api_handlers.py @@ -55,13 +55,6 @@ async def hacs_settings(hass, connection, msg): elif action == "set_fe_compact_false": hacs.configuration.frontend_compact = True - elif action == "reload_data": - hacs.system.status.reloading_data = True - hass.bus.async_fire("hacs/status", {}) - await hacs.recuring_tasks_all() - hacs.system.status.reloading_data = False - hass.bus.async_fire("hacs/status", {}) - elif action == "upgrade_all": hacs.system.status.upgrading_all = True hacs.system.status.background_task = True @@ -79,9 +72,7 @@ async def hacs_settings(hass, connection, msg): for repo in hacs.repositories: if msg.get("category") == repo.data.category: if repo.status.new: - hacs.logger.debug( - f"Clearing new flag from '{repo.data.full_name}'" - ) + hacs.logger.debug(f"Clearing new flag from '{repo.data.full_name}'") repo.status.new = False else: hacs.logger.error(f"WS action '{action}' is not valid") @@ -212,11 +203,10 @@ async def hacs_repository(hass, connection, msg): was_installed = repository.status.installed await repository.install() if not was_installed: - hass.bus.async_fire("hacs/reload", {"force": False}) + hass.bus.async_fire("hacs/reload", {"force": True}) elif action == "uninstall": await repository.uninstall() - hass.bus.async_fire("hacs/reload", {"force": False}) elif action == "hide": repository.status.hide = True @@ -243,19 +233,26 @@ async def hacs_repository(hass, connection, msg): repository.status.selected_tag = msg["version"] await repository.update_repository() + hass.bus.async_fire("hacs/reload", {"force": True}) + else: hacs.logger.error(f"WS action '{action}' is not valid") - repository.state = None await hacs.data.async_write() + message = None except AIOGitHubException as exception: + message = str(exception) hass.bus.async_fire("hacs/error", {"message": str(exception)}) except AttributeError as exception: - hass.bus.async_fire( - "hacs/error", {"message": f"Could not use repository with ID {repo_id}"} - ) + message = f"Could not use repository with ID {repo_id}" except Exception as exception: # pylint: disable=broad-except - hass.bus.async_fire("hacs/error", {"message": str(exception)}) + message = str(exception) + + if message is not None: + hacs.logger.error(message) + hass.bus.async_fire("hacs/error", {"message": message}) + + repository.state = None @websocket_api.async_response diff --git a/config/script/speech_processing.yaml b/config/script/speech_processing.yaml index f2887d10..0b6f80af 100755 --- a/config/script/speech_processing.yaml +++ b/config/script/speech_processing.yaml @@ -75,7 +75,7 @@ speech_processing: {% if states.group.bed.state == 'off' %} media_player.livingroomCC {% else %} - media_player.alarm_clock, media_player.bedroom_alarm_panel + media_player.tap {% endif %} message: >- diff --git a/config/www/custom_ui/floorplan/images/branding/att_speedtest.png b/config/www/custom_ui/floorplan/images/branding/att_speedtest.png index 3cf693ad..1d73d48e 100644 Binary files a/config/www/custom_ui/floorplan/images/branding/att_speedtest.png and b/config/www/custom_ui/floorplan/images/branding/att_speedtest.png differ diff --git a/config/www/custom_ui/floorplan/images/branding/solar_readings.png b/config/www/custom_ui/floorplan/images/branding/solar_readings.png index e9db7f50..2c90a754 100644 Binary files a/config/www/custom_ui/floorplan/images/branding/solar_readings.png and b/config/www/custom_ui/floorplan/images/branding/solar_readings.png differ