From 2a229df624457c24ea837166b7c47f6ce5e7a4d0 Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Fri, 7 Aug 2020 08:42:38 -0500 Subject: [PATCH 01/38] Change English/default naming of configure ui (#6555) --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index bb692bf03b..48d51fa5aa 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1890,7 +1890,7 @@ "confirm_delete_existing_cards_text": "Are you sure you want to delete your ''{name}'' view? The view contains {number} cards that will be deleted. This action cannot be undone." }, "menu": { - "configure_ui": "Configure UI", + "configure_ui": "Edit Dashboard", "help": "Help", "refresh": "Refresh", "reload_resources": "Reload resources", From 947773a82e0fd4d2933594fdc9bb7dd5aa6cd43b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Fri, 7 Aug 2020 15:47:25 +0200 Subject: [PATCH 02/38] Add diagnostics toggle (#6525) * Add diagnostics toggle * No need to check * Expected blank line between class members * Mimic the profile page * Move settings-row to components and use button * Update src/components/ha-settings-row.ts Co-authored-by: Bram Kragten Co-authored-by: Bram Kragten --- hassio/src/system/hassio-supervisor-info.ts | 70 ++++++++++++++++++- src/components/ha-settings-row.ts | 59 ++++++++++++++++ src/data/hassio/supervisor.ts | 1 + src/panels/profile/ha-advanced-mode-row.ts | 2 +- src/panels/profile/ha-force-narrow-row.ts | 2 +- .../ha-long-lived-access-tokens-card.js | 2 +- src/panels/profile/ha-pick-dashboard-row.ts | 2 +- src/panels/profile/ha-pick-language-row.js | 2 +- src/panels/profile/ha-pick-theme-row.ts | 2 +- .../profile/ha-push-notifications-row.js | 2 +- src/panels/profile/ha-refresh-tokens-card.js | 2 +- src/panels/profile/ha-set-suspend-row.ts | 2 +- src/panels/profile/ha-set-vibrate-row.ts | 2 +- src/panels/profile/ha-settings-row.js | 48 ------------- 14 files changed, 138 insertions(+), 60 deletions(-) create mode 100644 src/components/ha-settings-row.ts delete mode 100644 src/panels/profile/ha-settings-row.js diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 1843cb4058..7423da51a8 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -17,7 +17,12 @@ import { setSupervisorOption, SupervisorOptions, } from "../../../src/data/hassio/supervisor"; -import { showConfirmationDialog } from "../../../src/dialogs/generic/show-dialog-box"; +import "../../../src/components/ha-switch"; +import { + showConfirmationDialog, + showAlertDialog, +} from "../../../src/dialogs/generic/show-dialog-box"; +import "../../../src/components/ha-settings-row"; import { haStyle } from "../../../src/resources/styles"; import { HomeAssistant } from "../../../src/types"; import { hassioStyle } from "../resources/hassio-style"; @@ -55,6 +60,26 @@ class HassioSupervisorInfo extends LitElement { : ""} +
+ + + Share Diagnostics + + + Share crash reports and diagnostic information. + + + + +
${this._errors ? html`
Error: ${this._errors}
` : ""} @@ -111,7 +136,8 @@ class HassioSupervisorInfo extends LitElement { box-sizing: border-box; height: calc(100% - 47px); } - .info { + .info, + .options { width: 100%; } .info td:nth-child(2) { @@ -121,6 +147,12 @@ class HassioSupervisorInfo extends LitElement { color: var(--error-color); margin-top: 16px; } + ha-settings-row { + padding: 0; + } + button.link { + color: var(--primary-color); + } `, ]; } @@ -181,6 +213,40 @@ class HassioSupervisorInfo extends LitElement { this._errors = `Error joining beta channel, ${err.body?.message || err}`; } } + + private async _diagnosticsInformationDialog() { + await showAlertDialog(this, { + title: "Help Improve Home Assistant", + text: html`Would you want to automatically share crash reports and + diagnostic information when the supervisor encounters unexpected errors? +

+ This will allow us to fix the problems, the information is only + accessible to the Home Assistant Core team and will not be shared with + others. +

+ The data does not include any private/sensetive information and you can + disable this in settings at any time you want.`, + }); + } + + private async _toggleDiagnostics() { + try { + const data: SupervisorOptions = { + diagnostics: !this.supervisorInfo?.diagnostics, + }; + await setSupervisorOption(this.hass, data); + const eventdata = { + success: true, + response: undefined, + path: "option", + }; + fireEvent(this, "hass-api-called", eventdata); + } catch (err) { + this._errors = `Error changing supervisor setting, ${ + err.body?.message || err + }`; + } + } } declare global { diff --git a/src/components/ha-settings-row.ts b/src/components/ha-settings-row.ts new file mode 100644 index 0000000000..43c886ab99 --- /dev/null +++ b/src/components/ha-settings-row.ts @@ -0,0 +1,59 @@ +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + SVGTemplateResult, +} from "lit-element"; +import "@polymer/paper-item/paper-item-body"; + +@customElement("ha-settings-row") +export class HaSettingsRow extends LitElement { + @property({ type: Boolean, reflect: true }) public narrow!: boolean; + + @property({ type: Boolean, attribute: "three-line" }) + public threeLine = false; + + protected render(): SVGTemplateResult { + return html` + + + +
+
+ + `; + } + + static get styles(): CSSResult { + return css` + :host { + display: flex; + padding: 0 16px; + align-content: normal; + align-self: auto; + align-items: center; + } + :host([narrow]) { + align-items: normal; + flex-direction: column; + border-top: 1px solid var(--divider-color); + padding-bottom: 8px; + } + `; + } +} +declare global { + interface HTMLElementTagNameMap { + "ha-settings-row": HaSettingsRow; + } +} diff --git a/src/data/hassio/supervisor.ts b/src/data/hassio/supervisor.ts index e32e13ad2f..51454ad610 100644 --- a/src/data/hassio/supervisor.ts +++ b/src/data/hassio/supervisor.ts @@ -31,6 +31,7 @@ export interface CreateSessionResponse { export interface SupervisorOptions { channel?: "beta" | "dev" | "stable"; + diagnostics?: boolean; addons_repositories?: string[]; } diff --git a/src/panels/profile/ha-advanced-mode-row.ts b/src/panels/profile/ha-advanced-mode-row.ts index a7e40b16cf..4cd23aa8df 100644 --- a/src/panels/profile/ha-advanced-mode-row.ts +++ b/src/panels/profile/ha-advanced-mode-row.ts @@ -14,7 +14,7 @@ import { getOptimisticFrontendUserDataCollection, } from "../../data/frontend"; import { HomeAssistant } from "../../types"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; @customElement("ha-advanced-mode-row") class AdvancedModeRow extends LitElement { diff --git a/src/panels/profile/ha-force-narrow-row.ts b/src/panels/profile/ha-force-narrow-row.ts index edf8c5e19c..a11616ab36 100644 --- a/src/panels/profile/ha-force-narrow-row.ts +++ b/src/panels/profile/ha-force-narrow-row.ts @@ -9,7 +9,7 @@ import { fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-switch"; import type { HaSwitch } from "../../components/ha-switch"; import type { HomeAssistant } from "../../types"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; @customElement("ha-force-narrow-row") class HaForcedNarrowRow extends LitElement { diff --git a/src/panels/profile/ha-long-lived-access-tokens-card.js b/src/panels/profile/ha-long-lived-access-tokens-card.js index 4b9697de48..5943164610 100644 --- a/src/panels/profile/ha-long-lived-access-tokens-card.js +++ b/src/panels/profile/ha-long-lived-access-tokens-card.js @@ -13,7 +13,7 @@ import { import { EventsMixin } from "../../mixins/events-mixin"; import LocalizeMixin from "../../mixins/localize-mixin"; import "../../styles/polymer-ha-style"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; /* * @appliesMixin EventsMixin diff --git a/src/panels/profile/ha-pick-dashboard-row.ts b/src/panels/profile/ha-pick-dashboard-row.ts index 33fde87943..c8e9765b56 100644 --- a/src/panels/profile/ha-pick-dashboard-row.ts +++ b/src/panels/profile/ha-pick-dashboard-row.ts @@ -13,7 +13,7 @@ import "../../components/ha-paper-dropdown-menu"; import { fetchDashboards, LovelaceDashboard } from "../../data/lovelace"; import { setDefaultPanel } from "../../data/panel"; import { HomeAssistant } from "../../types"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; @customElement("ha-pick-dashboard-row") class HaPickDashboardRow extends LitElement { diff --git a/src/panels/profile/ha-pick-language-row.js b/src/panels/profile/ha-pick-language-row.js index 8ec1ccd6ad..59019e027a 100644 --- a/src/panels/profile/ha-pick-language-row.js +++ b/src/panels/profile/ha-pick-language-row.js @@ -6,7 +6,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element"; import "../../components/ha-paper-dropdown-menu"; import { EventsMixin } from "../../mixins/events-mixin"; import LocalizeMixin from "../../mixins/localize-mixin"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; /* * @appliesMixin LocalizeMixin diff --git a/src/panels/profile/ha-pick-theme-row.ts b/src/panels/profile/ha-pick-theme-row.ts index 84d5dd4992..f78b827553 100644 --- a/src/panels/profile/ha-pick-theme-row.ts +++ b/src/panels/profile/ha-pick-theme-row.ts @@ -12,7 +12,7 @@ import { css, } from "lit-element"; import { HomeAssistant } from "../../types"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; import { fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-formfield"; import "../../components/ha-radio"; diff --git a/src/panels/profile/ha-push-notifications-row.js b/src/panels/profile/ha-push-notifications-row.js index ee2019a5b4..7f0bbc0af0 100644 --- a/src/panels/profile/ha-push-notifications-row.js +++ b/src/panels/profile/ha-push-notifications-row.js @@ -6,7 +6,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { pushSupported } from "../../components/ha-push-notifications-toggle"; import LocalizeMixin from "../../mixins/localize-mixin"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; /* * @appliesMixin LocalizeMixin diff --git a/src/panels/profile/ha-refresh-tokens-card.js b/src/panels/profile/ha-refresh-tokens-card.js index 81f83b41c5..e4f7e4f58c 100644 --- a/src/panels/profile/ha-refresh-tokens-card.js +++ b/src/panels/profile/ha-refresh-tokens-card.js @@ -11,7 +11,7 @@ import { showAlertDialog, showConfirmationDialog, } from "../../dialogs/generic/show-dialog-box"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; /* * @appliesMixin EventsMixin diff --git a/src/panels/profile/ha-set-suspend-row.ts b/src/panels/profile/ha-set-suspend-row.ts index a2ead43255..f734c7c0c7 100644 --- a/src/panels/profile/ha-set-suspend-row.ts +++ b/src/panels/profile/ha-set-suspend-row.ts @@ -9,7 +9,7 @@ import { fireEvent, HASSDomEvent } from "../../common/dom/fire_event"; import "../../components/ha-switch"; import type { HaSwitch } from "../../components/ha-switch"; import type { HomeAssistant } from "../../types"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; declare global { // for fire event diff --git a/src/panels/profile/ha-set-vibrate-row.ts b/src/panels/profile/ha-set-vibrate-row.ts index e232c510ae..e5ae63ad88 100644 --- a/src/panels/profile/ha-set-vibrate-row.ts +++ b/src/panels/profile/ha-set-vibrate-row.ts @@ -10,7 +10,7 @@ import "../../components/ha-switch"; import type { HaSwitch } from "../../components/ha-switch"; import { forwardHaptic } from "../../data/haptics"; import type { HomeAssistant } from "../../types"; -import "./ha-settings-row"; +import "../../components/ha-settings-row"; @customElement("ha-set-vibrate-row") class HaSetVibrateRow extends LitElement { diff --git a/src/panels/profile/ha-settings-row.js b/src/panels/profile/ha-settings-row.js deleted file mode 100644 index 15ddb6c917..0000000000 --- a/src/panels/profile/ha-settings-row.js +++ /dev/null @@ -1,48 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -class HaSettingsRow extends PolymerElement { - static get template() { - return html` - - - -
-
- - `; - } - - static get properties() { - return { - narrow: { - type: Boolean, - reflectToAttribute: true, - }, - threeLine: { - type: Boolean, - value: false, - }, - }; - } -} - -customElements.define("ha-settings-row", HaSettingsRow); From 49683326e6822591a2fa9bc3fe57eed05aa4a873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Fri, 7 Aug 2020 15:59:22 +0200 Subject: [PATCH 03/38] Reorder to not break jinja templates (#6564) --- src/html/index.html.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/html/index.html.template b/src/html/index.html.template index 0225c9b3ab..fe4271c0fb 100644 --- a/src/html/index.html.template +++ b/src/html/index.html.template @@ -47,12 +47,12 @@ background-color: var(--primary-background-color); } @media (prefers-color-scheme: dark) { - #ha-init-skeleton::before { - background-color: #1c1c1c; - } html { background-color: #111111; } + #ha-init-skeleton::before { + background-color: #1c1c1c; + } } From 02791c51ae0f44005fdf1cec31b99b56002f642a Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Fri, 7 Aug 2020 14:00:10 +0000 Subject: [PATCH 04/38] Bumped version to 20200807.1 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f4c217e8bd..834ffe3aab 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20200807.0", + version="20200807.1", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", From 9877f08cf46a2a1370fd53d8b61bf7a5004a6f0d Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Sat, 8 Aug 2020 00:32:34 +0000 Subject: [PATCH 05/38] [ci skip] Translation update --- translations/frontend/en.json | 2 +- translations/frontend/es.json | 2 +- translations/frontend/fi.json | 61 +++++++++++++++++++++++++++++++++-- translations/frontend/ru.json | 25 ++++++++++++-- translations/frontend/vi.json | 2 +- 5 files changed, 83 insertions(+), 9 deletions(-) diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 8b1ae3070f..e43714330a 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "Close", - "configure_ui": "Configure UI", + "configure_ui": "Edit Dashboard", "exit_edit_mode": "Exit UI edit mode", "help": "Help", "refresh": "Refresh", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 6241c73978..84ae39b6bf 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -201,7 +201,7 @@ }, "climate": { "cool": "Frío", - "dry": "Seco", + "dry": "Deshumidificador", "fan_only": "Sólo ventilador", "heat": "Calor", "heat_cool": "Calor/Frío", diff --git a/translations/frontend/fi.json b/translations/frontend/fi.json index 513f71cfbf..61305a4074 100644 --- a/translations/frontend/fi.json +++ b/translations/frontend/fi.json @@ -798,7 +798,7 @@ "confirmation_text": "Tälle alueelle kuuluvien laitteiden osoitus poistetaan.", "confirmation_title": "Haluatko varmasti poistaa tämän alueen?" }, - "description": "Yleiskuva kaikista kotisi alueista.", + "description": "Hallinnoi kotisi alueita", "editor": { "area_id": "Alueen tunnus", "create": "Luo", @@ -833,6 +833,15 @@ "name": "Toiminta", "type_select": "Toiminnon tyyppi", "type": { + "choose": { + "add_option": "Lisää vaihtoehto", + "conditions": "Ehdot", + "default": "Oletustoiminnot", + "label": "Valitse", + "option": "Vaihtoehto {number}", + "remove_option": "Poista vaihtoehto", + "sequence": "Toiminnot" + }, "condition": { "label": "Ehto" }, @@ -852,6 +861,24 @@ "label": "Lähetä tapahtuma", "service_data": "Palvelun data" }, + "repeat": { + "label": "Toista", + "sequence": "Toiminnot", + "type_select": "Toistotyyppi", + "type": { + "count": { + "label": "Laske" + }, + "until": { + "conditions": "Kunnes ehdot", + "label": "Kunnes" + }, + "while": { + "conditions": "Sillä aikaa, kun ehdot", + "label": "Sillä aikaa" + } + } + }, "scene": { "label": "Aktivoi tilanne" }, @@ -1341,7 +1368,7 @@ }, "entities": { "caption": "Kohteet", - "description": "Yleiskuva kaikista tunnetuista entiteeteistä.", + "description": "Hallitse kohteita", "picker": { "disable_selected": { "button": "Poista valitut käytöstä", @@ -1619,6 +1646,18 @@ "title": "MQTT", "topic": "aihe" }, + "ozw": { + "common": { + "node_id": "Solmun tunnus", + "ozw_instance": "OpenZWave-instanssi", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Solmu epäonnistui", + "stage": "Vaihe", + "zwave_info": "Z-Wave-tiedot" + } + }, "person": { "add_person": "Lisää henkilö", "caption": "Henkilöt", @@ -1711,6 +1750,7 @@ "queued": "Jonon pituus" }, "modes": { + "description": "Moodi hallitsee sitä, mitä tapahtuu, kun skripti käynnistetään, kun se edelleen toimii yhdestä tai useammasta aiemmasta kutsusta. Katso lisätietoja {documentation_link} .", "documentation": "skriptin dokumentaatio", "label": "Tila", "parallel": "Rinnakkain", @@ -2386,6 +2426,9 @@ "para_migrate": "Home Assistant voi lisätä ID:t kaikkiin kortteihisi ja näkymiin automaattisesti painamalla 'Tuo vanhat asetukset'-nappia.", "para_no_id": "Elementillä ei ole ID. Lisää ID elementille 'ui-lovelace.yaml'-tiedostossa." }, + "move_card": { + "header": "Valitse näkymä, johon kortti siirretään" + }, "raw_editor": { "confirm_remove_config_text": "Lovelace käyttöliittymän näkymät luodaan automaattisesti alueistasi ja laitteistasi, jos poistat nykyisen määrityksen.", "confirm_remove_config_title": "Haluatko varmasti poistaa Lovelace-käyttöliittymän asetukset? Lovelace käyttöliittymän asetukset luodaan automaattisesti alueistasi ja laitteistasi.", @@ -2413,6 +2456,10 @@ "yaml_control": "Jos haluat hallita YAML-tilaa, luo YAML-tiedosto, jonka nimi on määritetty tämän kojelaudan kokoonpanossa, tai oletusarvoinen 'ui-lovelace.yaml'.", "yaml_mode": "Käytät YAML-tilaa, mikä tarkoittaa, että et voi muuttaa Lovelace-asetuksia käyttöliittymästä. Jos haluat muuttaa Lovelacea käyttöliittymästä, poista 'mode: yaml' Lovelace-määrityksestäsi tiedostossa 'configuration.yaml'." }, + "select_view": { + "dashboard_label": "Kojelauta", + "header": "Valitse näkymä" + }, "suggest_card": { "add": "Lisää Lovelace-käyttöliittymään", "create_own": "Valitse toinen kortti", @@ -2730,10 +2777,18 @@ "header": "Sulje yhteys automaattisesti" }, "themes": { + "accent_color": "Korostusväri", + "dark_mode": { + "auto": "Automaattinen", + "dark": "Tumma", + "light": "Vaalea" + }, "dropdown_label": "Teema", "error_no_theme": "Ei teemoja käytettävissä.", "header": "Teema", - "link_promo": "Lisätietoja teemoista" + "link_promo": "Lisätietoja teemoista", + "primary_color": "Ensisijainen väri", + "reset": "Nollaa" }, "vibrate": { "description": "Ota tämän laitteen värinä käyttöön tai poista se käytöstä, kun ohjaat laitteita.", diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 15337b2b0b..a9069a8f15 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -834,11 +834,12 @@ "type_select": "Тип действия", "type": { "choose": { - "add_option": "Добавить опцию", + "add_option": "Добавить вариант", "conditions": "Условия", "default": "Действия по умолчанию", - "option": "Опция {number}", - "remove_option": "Удалить опцию", + "label": "Выбор", + "option": "{number} вариант", + "remove_option": "Удалить вариант", "sequence": "Действия" }, "condition": { @@ -860,6 +861,24 @@ "label": "Создание события", "service_data": "Данные" }, + "repeat": { + "label": "Повтор", + "sequence": "Действия", + "type_select": "Режим повторений", + "type": { + "count": { + "label": "Счётчик" + }, + "until": { + "conditions": "Действия будут выполняться в цикле до тех пор, когда начнут соблюдаться эти условия", + "label": "До" + }, + "while": { + "conditions": "Действия будут выполняться в цикле, пока соблюдаются эти условия", + "label": "Пока" + } + } + }, "scene": { "label": "Активировать сцену" }, diff --git a/translations/frontend/vi.json b/translations/frontend/vi.json index 5c5bae4ba5..dc48b79412 100644 --- a/translations/frontend/vi.json +++ b/translations/frontend/vi.json @@ -918,7 +918,7 @@ }, "mqtt": { "label": "MQTT", - "payload": "Phụ tải (tùy chọn)", + "payload": "Nội dung (tùy chọn)", "topic": "Chủ đề" }, "numeric_state": { From 01df10f93ebb70ba76414ad5397aaf3646412fae Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Sun, 9 Aug 2020 00:32:33 +0000 Subject: [PATCH 06/38] [ci skip] Translation update --- translations/frontend/ca.json | 44 ++++++------- translations/frontend/fy.json | 118 +++++++++++++++++++++++++++++++++- translations/frontend/nl.json | 17 ++++- translations/frontend/ru.json | 2 +- 4 files changed, 156 insertions(+), 25 deletions(-) diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index 5ceba7af7b..cb4122cf4a 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -798,7 +798,7 @@ "confirmation_text": "Tots els dispositius d'aquesta àrea quedaran sense assignar.", "confirmation_title": "Estàs segur que vols eliminar aquesta àrea?" }, - "description": "Visió general de totes les àrees de la casa.", + "description": "Gestiona les àrees de la casa", "editor": { "area_id": "ID d'àrea", "create": "Crea", @@ -820,7 +820,7 @@ }, "automation": { "caption": "Automatització", - "description": "Crea i edita automatitzacions", + "description": "Gestiona les automatitzacions", "editor": { "actions": { "add": "Afegir acció", @@ -837,9 +837,9 @@ "add_option": "Afegeix opció", "conditions": "Condicions", "default": "Accions per defecte", - "label": "Triar", + "label": "Tria", "option": "Opció {number}", - "remove_option": "Eliminar opció", + "remove_option": "Elimina opció", "sequence": "Accions" }, "condition": { @@ -862,19 +862,19 @@ "service_data": "Dades de servei" }, "repeat": { - "label": "Repetir", + "label": "Repeteix", "sequence": "Accions", "type_select": "Tipus de repetició", "type": { "count": { - "label": "Comptar" + "label": "Compta" }, "until": { - "conditions": "Fins a les condicions", + "conditions": "Condicions de \"Fins que\"", "label": "Fins que" }, "while": { - "conditions": "Mentre que les condicions", + "conditions": "Condicions de \"Mentre\"", "label": "Mentre" } } @@ -1368,7 +1368,7 @@ }, "entities": { "caption": "Entitats", - "description": "Visió general de totes les entitats conegudes.", + "description": "Gestiona les entitats conegudes", "picker": { "disable_selected": { "button": "Desactiva seleccionada/es", @@ -1420,7 +1420,7 @@ "header": "Configuració de Home Assistant", "helpers": { "caption": "Ajudants", - "description": "Possibles elements útils per a construir automatitzacions.", + "description": "Gestiona elements útils per a construir automatitzacions", "dialog": { "add_helper": "Afegeix ajudant", "add_platform": "Afegeix {platform}", @@ -1448,7 +1448,7 @@ "built_using": "Creat utilitzant", "caption": "Informació", "custom_uis": "Interfícies d'usuari personalitzades:", - "description": "Informació de la instal·lació de Home Assistant", + "description": "Consulta informació de la teva instal·lació de Home Assistant", "developed_by": "Desenvolupat per un munt de gent fantàstica.", "documentation": "Documentació", "frontend": "frontend-ui", @@ -1513,7 +1513,7 @@ }, "configure": "Configurar", "configured": "Configurades", - "description": "Gestiona i configura les integracions", + "description": "Gestiona les integracions", "details": "Detalls de la integració", "discovered": "Descobertes", "home_assistant_website": "lloc web de Home Assistant", @@ -1541,7 +1541,7 @@ "rename_input_label": "Nom de l'entrada", "search": "Cerca integracions" }, - "introduction": "Aquí pots configurar Home Assistant i els seus components. Encara no és possible configurar-ho tot des de la interfície d'usuari, però hi estem treballant.", + "introduction": "Aquí pots configurar Home Assistant i els teus components. Encara no és possible configurar-ho tot des de la interfície d'usuari, però hi estem treballant.", "logs": { "caption": "Registres", "clear": "Esborra", @@ -1597,7 +1597,7 @@ "open": "Obrir" } }, - "description": "Configura els teus panells Lovelace", + "description": "Gestiona els teus panells Lovelace", "resources": { "cant_edit_yaml": "Estàs utilitzant Lovelace en mode YAML per tant no pots gestionar els recursos des de la interfície d'usuari. Els pots gestionar des del fitxer 'configuration.yaml'.", "caption": "Recursos", @@ -1648,7 +1648,7 @@ }, "ozw": { "common": { - "node_id": "Node ID", + "node_id": "ID del node", "ozw_instance": "Instància OpenZWave", "zwave": "Z-Wave" }, @@ -1664,7 +1664,7 @@ "confirm_delete": "Estàs segur que vols eliminar aquesta persona?", "confirm_delete2": "Tots els dispositius vinculats a aquesta persona quedaran sense assignar.", "create_person": "Crea persona", - "description": "Gestiona a quines persones fa seguiment Home Assistant.", + "description": "Gestiona les persones a qui Home Assistant fa seguiment", "detail": { "create": "Crea", "delete": "Elimina", @@ -1687,7 +1687,7 @@ "scene": { "activated": "Escena {name} activada.", "caption": "Escenes", - "description": "Crea i edita escenes", + "description": "Gestiona les escenes", "editor": { "default_name": "Nova escena", "devices": { @@ -1731,7 +1731,7 @@ }, "script": { "caption": "Programació (scripts)", - "description": "Crea i edita programes (scripts)", + "description": "Gestiona els programes (scripts)", "editor": { "alias": "Nom", "default_name": "Nou script", @@ -1918,7 +1918,7 @@ "create_group": "Domòtica Zigbee (ZHA) - Creació de grups", "create_group_details": "Introdueix els detalls necessaris per crear un nou grup Zigbee", "creating_group": "Creant grup", - "description": "Crea i modifica grups Zigbee", + "description": "Gestiona els grups Zigbee", "group_details": "Detalls del grup Zigbee seleccionat.", "group_id": "ID del grup", "group_info": "Informació del grup", @@ -1961,7 +1961,7 @@ "configured_in_yaml": "Les zones configurades mitjançant configuration.yaml no es poden editar des de la UI.", "confirm_delete": "Estàs segur que vols eliminar aquesta zona?", "create_zone": "Crea zona", - "description": "Gestiona les zones en les quals es fa seguiment de persones.", + "description": "Gestiona les zones en les quals vols fer seguiment de persones", "detail": { "create": "Crea", "delete": "Elimina", @@ -2475,7 +2475,7 @@ }, "menu": { "close": "Tanca", - "configure_ui": "Configurar la interfície d'usuari", + "configure_ui": "Edita panell", "exit_edit_mode": "Surt del mode d'edició d'interfície", "help": "Ajuda", "refresh": "Actualitzar", @@ -2777,7 +2777,7 @@ "header": "Tanca la connexió automàticament" }, "themes": { - "accent_color": "Color accent", + "accent_color": "Color d'èmfasi", "dark_mode": { "auto": "Auto", "dark": "Fosc", diff --git a/translations/frontend/fy.json b/translations/frontend/fy.json index 9e26dfeeb6..c352177f6f 100644 --- a/translations/frontend/fy.json +++ b/translations/frontend/fy.json @@ -1 +1,117 @@ -{} \ No newline at end of file +{ + "panel": { + "config": "Konfiguraasje", + "history": "Skiednis", + "shopping_list": "Boadskiplist" + }, + "state_attributes": { + "climate": { + "fan_mode": { + "off": "Út" + } + } + }, + "state_badge": { + "person": { + "home": "Thús" + } + }, + "state": { + "binary_sensor": { + "default": { + "on": "Oan" + }, + "garage_door": { + "off": "Ticht", + "on": "Iepen" + }, + "opening": { + "off": "Ticht" + }, + "presence": { + "on": "Thús" + } + }, + "calendar": { + "on": "Oan" + }, + "cover": { + "open": "Iepen" + }, + "default": { + "off": "Út", + "unavailable": "Net beskikber", + "unknown": "Ûnbekend" + }, + "device_tracker": { + "not_home": "Fuort" + }, + "fan": { + "on": "Oan" + }, + "group": { + "home": "Thús", + "open": "Iepen", + "stopped": "Stoppe" + }, + "light": { + "off": "Út" + }, + "script": { + "off": "Út" + }, + "sensor": { + "off": "Út", + "on": "Oan" + }, + "switch": { + "on": "Oan" + }, + "weather": { + "sunny": "Sinnich" + } + }, + "ui": { + "dialogs": { + "zha_device_info": { + "zha_device_card": { + "device_name_placeholder": "Feroarje apparaatnamme" + } + } + }, + "panel": { + "config": { + "automation": { + "editor": { + "actions": { + "type": { + "choose": { + "add_option": "Opsje tafoegje" + }, + "repeat": { + "sequence": "Aksjes" + } + } + } + } + }, + "helpers": { + "types": { + "input_boolean": "Skeakelje", + "input_number": "Nûmer" + } + }, + "info": { + "description": "Ynformaasje oer dyn Home Assistant ynstallaasje" + }, + "lovelace": { + "resources": { + "detail": { + "warning_header": "Wês foarsichtich!" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index 3c01b2a6c1..5cbb821fbe 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -833,6 +833,13 @@ "name": "Actie", "type_select": "Type actie", "type": { + "choose": { + "add_option": "Optie toevoegen", + "conditions": "Voorwaarden", + "label": "Kies", + "remove_option": "Verwijder optie", + "sequence": "Acties" + }, "condition": { "label": "Voorwaarde" }, @@ -2412,6 +2419,9 @@ "yaml_control": "Om de controle over te nemen in de YAML-modus, maak je een YAML-bestand met de naam die je hebt opgegeven in je configuratie voor dit dashboard, of de standaard 'ui-lovelace.yaml'.", "yaml_mode": "Je gebruikt de YAML-modus, wat betekent dat je jouw Lovelace-configuratie niet vanuit de gebruikersinterface kunt wijzigen. Als je Lovelace vanuit de gebruikersinterface wilt wijzigen, verwijder dan 'mode: yaml' uit de Lovelace-configuratie in 'configuration.yaml'." }, + "select_view": { + "dashboard_label": "Dashboard" + }, "suggest_card": { "add": "Voeg toe aan de Lovelace gebruikersinterface", "create_own": "Kies een andere kaart", @@ -2729,10 +2739,15 @@ "header": "Verbinding automatisch verbreken" }, "themes": { + "dark_mode": { + "dark": "Donker", + "light": "Licht" + }, "dropdown_label": "Thema", "error_no_theme": "Geen thema's beschikbaar.", "header": "Thema", - "link_promo": "Meer informatie over thema's" + "link_promo": "Meer informatie over thema's", + "primary_color": "Primaire kleur" }, "vibrate": { "description": "Schakel trillingen op dit apparaat in of uit wanneer u apparaten bestuurt.", diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index a9069a8f15..6abedb94c4 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "Закрыть", - "configure_ui": "Настройка интерфейса", + "configure_ui": "Изменить панель", "exit_edit_mode": "Выход из режима редактирования интерфейса", "help": "Справка", "refresh": "Обновить", From c705e74fc85d36d119f71d61267baf33e6c7b7cc Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Mon, 10 Aug 2020 00:32:35 +0000 Subject: [PATCH 07/38] [ci skip] Translation update --- translations/frontend/es.json | 2 +- translations/frontend/fy.json | 115 +++++++++++++++++++++++++++++++++- translations/frontend/tr.json | 77 ++++++++++++++++++++--- 3 files changed, 181 insertions(+), 13 deletions(-) diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 84ae39b6bf..f5b4dabc25 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "Cerrar", - "configure_ui": "Configurar la interfaz de usuario", + "configure_ui": "Editar panel de control", "exit_edit_mode": "Salir del modo de edición de la interfaz de usuario", "help": "Ayuda", "refresh": "Actualizar", diff --git a/translations/frontend/fy.json b/translations/frontend/fy.json index c352177f6f..9d3024376c 100644 --- a/translations/frontend/fy.json +++ b/translations/frontend/fy.json @@ -2,6 +2,8 @@ "panel": { "config": "Konfiguraasje", "history": "Skiednis", + "mailbox": "Postfak", + "map": "Kaart", "shopping_list": "Boadskiplist" }, "state_attributes": { @@ -17,24 +19,57 @@ } }, "state": { + "alarm_control_panel": { + "triggered": "Aktivearre" + }, "binary_sensor": { + "cold": { + "on": "Kâld" + }, + "connectivity": { + "on": "Ferbûn" + }, "default": { "on": "Oan" }, + "door": { + "off": "Ticht", + "on": "Iepen" + }, "garage_door": { "off": "Ticht", "on": "Iepen" }, + "gas": { + "off": "Net detektearre" + }, + "motion": { + "on": "Detekteare" + }, "opening": { "off": "Ticht" }, "presence": { "on": "Thús" + }, + "vibration": { + "on": "Detekteare" + }, + "window": { + "off": "Ticht" } }, "calendar": { "on": "Oan" }, + "camera": { + "recording": "Opnimme" + }, + "climate": { + "cool": "Kuolje", + "dry": "Droech", + "heat": "Ferwaarmje" + }, "cover": { "open": "Iepen" }, @@ -51,12 +86,19 @@ }, "group": { "home": "Thús", + "locked": "Beskoattele", "open": "Iepen", "stopped": "Stoppe" }, "light": { "off": "Út" }, + "lock": { + "locked": "Beskoattele" + }, + "media_player": { + "playing": "Ôfspylje" + }, "script": { "off": "Út" }, @@ -69,9 +111,22 @@ }, "weather": { "sunny": "Sinnich" + }, + "zwave": { + "default": { + "dead": "Net berikber", + "initializing": "Inisjalisearje", + "sleeping": "Sliept" + }, + "query_stage": { + "dead": "Net berikber ({query_stage})" + } } }, "ui": { + "common": { + "loading": "Oan it laden" + }, "dialogs": { "zha_device_info": { "zha_device_card": { @@ -79,6 +134,11 @@ } } }, + "duration": { + "day": "{count} {count, plural,\none {dei}\nother {dagen}\n}", + "second": "{count} {count, plural,\none {sekonde}\nother {sekonden}\n}", + "week": "{count} {count, plural,\none {wike}\nother {wiken}\n}" + }, "panel": { "config": { "automation": { @@ -87,9 +147,24 @@ "type": { "choose": { "add_option": "Opsje tafoegje" + } + } + }, + "triggers": { + "add": "Trigger tafoegje", + "header": "", + "type": { + "homeassistant": { + "label": "", + "shutdown": "Ofslúte", + "start": "Opstarte" }, - "repeat": { - "sequence": "Aksjes" + "mqtt": { + "payload": "Payload (opsjoneel)" + }, + "state": { + "from": "Fan", + "to": "Nei" } } } @@ -105,11 +180,47 @@ "description": "Ynformaasje oer dyn Home Assistant ynstallaasje" }, "lovelace": { + "description": "Konfigurearje dyn Lovelace-dashboards", "resources": { "detail": { "warning_header": "Wês foarsichtich!" } } + }, + "script": { + "description": "Meitsje en bewurkje scripts" + }, + "zha": { + "groups": { + "description": "Meitsje en bewurkje Zigbee groepen" + } + }, + "zwave": { + "node_config": { + "config_value": "Konfiguraasje wearde" + } + } + }, + "lovelace": { + "editor": { + "select_view": { + "dashboard_label": "Dashboard" + } + }, + "menu": { + "configure_ui": "Konfigurearje UI" + } + }, + "mailbox": { + "playback_title": "Berjocht ôfspylje" + }, + "profile": { + "themes": { + "dark_mode": { + "dark": "Tsjuster", + "light": "ljocht" + }, + "primary_color": "Primêre kleur" } } } diff --git a/translations/frontend/tr.json b/translations/frontend/tr.json index 7844947073..0c2c4831f9 100644 --- a/translations/frontend/tr.json +++ b/translations/frontend/tr.json @@ -96,7 +96,7 @@ "armed": "Etkin", "armed_away": "Etkin dışarıda", "armed_custom_bypass": "Özel alarm atlatması", - "armed_home": "Etkin evde", + "armed_home": "Evdeyim modu kuruldu", "armed_night": "Etkin gece", "arming": "Etkinleşiyor", "disarmed": "Etkisiz", @@ -581,6 +581,7 @@ }, "dialogs": { "config_entry_system_options": { + "enable_new_entities_description": "Devre dışı bırakılırsa, {integration} için yeni keşfedilen varlıklar otomatik olarak Home Assistant'a eklenmez.", "enable_new_entities_label": "Yeni eklenen varlıkları etkinleştir.", "title": "{integration} için Sistem Seçenekleri", "update": "Güncelle" @@ -692,11 +693,14 @@ } }, "mqtt_device_debug_info": { + "deserialize": "MQTT mesajlarını JSON olarak ayrıştırma yap", "entities": "Varlıklar", "no_entities": "Varlık yok", "no_triggers": "Tetikleyici yok", + "payload_display": "Yük ekranı", "recent_messages": "{n} , en son alınan mesaj (lar)", "show_as_yaml": "YAML olarak göster", + "title": "{device} hata ayıklama bilgisi", "triggers": "Tetikleyiciler" }, "options_flow": { @@ -726,6 +730,7 @@ "confirmations": { "remove": "Cihazı kaldırmak istediğinize emin misiniz?" }, + "device_signature": "Zigbee cihaz imzası", "last_seen": "Son görülen", "manuf": "{manufacturer} tarafından", "no_area": "Alan Yok", @@ -733,7 +738,8 @@ "quirk": "Orijinal", "services": { "remove": "Bir cihazı Zigbee ağından kaldır.", - "updateDeviceName": "Aygıt kayıt defterinde bu aygıt için özel bir ad ayarlayın." + "updateDeviceName": "Aygıt kayıt defterinde bu aygıt için özel bir ad ayarlayın.", + "zigbee_information": "Cihazın Zigbee bilgilerini görüntüleyin." }, "unknown": "Bilinmeyen", "zha_device_card": { @@ -775,7 +781,7 @@ }, "config": { "advanced_mode": { - "hint_enable": "Eksik yapılandırma seçenekleri? Gelişmiş modunu etkinleştir", + "hint_enable": "Yapılandırma seçenekleri eksik mi? Gelişmiş modu etkinleştirin", "link_profile_page": "profil sayfanız" }, "areas": { @@ -821,6 +827,15 @@ "name": "Aksiyon", "type_select": "Aksiyon türü", "type": { + "choose": { + "add_option": "Seçenek ekle", + "conditions": "Koşullar", + "default": "Varsayılan eylemler", + "label": "Seç", + "option": "Seçenek {number}", + "remove_option": "Seçeneği kaldır", + "sequence": "Aksiyonlar" + }, "condition": { "label": "Durum" }, @@ -840,6 +855,15 @@ "label": "Olayı Çalıştır", "service_data": "Hizmet verisi" }, + "repeat": { + "sequence": "Aksiyonlar", + "type": { + "until": { + "conditions": "Koşullara kadar", + "label": "Kadar" + } + } + }, "scene": { "label": "Sahneyi etkinleştir" }, @@ -1220,7 +1244,7 @@ "save_button": "Kaydet", "time_zone": "Saat dilimi", "unit_system": "Birim Sistemi", - "unit_system_imperial": "ımperial", + "unit_system_imperial": "Imperial", "unit_system_metric": "Metrik" }, "header": "Yapılandırma ve sunucu kontrolü", @@ -1465,7 +1489,7 @@ "note_about_website_reference": "Daha fazlası için", "rename_dialog": "Bu yapılandırma girişinin adını düzenleyin", "rename_input_label": "Varlık adı", - "search": "Entegrasyonları ara" + "search": "Entegrasyon ara" }, "introduction": "Buradan bileşenlerinizi ve Home Assistant'ınızı yapılandırabilirsiniz. Herşeyi kullanıcı arayüzü ile ayarlamak henüz mümkün değil fakat üzerinde çalışıyoruz", "logs": { @@ -1569,6 +1593,18 @@ "title": "MQTT", "topic": "konu" }, + "ozw": { + "common": { + "node_id": "Düğüm Kimliği", + "ozw_instance": "OpenZWave Örneği", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Düğüm Başarısız", + "stage": "Sahne", + "zwave_info": "Z-Wave Bilgisi" + } + }, "person": { "add_person": "Kişi ekle", "caption": "Kişiler", @@ -1752,6 +1788,7 @@ "zha": { "add_device_page": { "discovered_text": "Cihazlar keşfedildikten sonra burada görünecektir.", + "discovery_text": "Keşfedilen cihazlar burada görünecektir. Cihaz (lar) ınız için talimatları izleyin ve cihazları eşleştirme moduna getirin.", "header": "Zigbee Ev Otomasyonu - Cihaz Ekle", "no_devices_found": "Hiçbir cihaz bulunamadı, eşleştirme modunda olduklarından emin olun ve keşfetme sırasında cihazı açık tutun.", "pairing_mode": "Cihazlarınızın eşleme modunda olduğundan emin olun. Bunun nasıl yapılacağı konusunda cihazınızın talimatlarını kontrol edin.", @@ -1916,6 +1953,7 @@ "set_protection": "Korumayı Ayarla" }, "ozw_log": { + "introduction": "Günlüğü görüntüleyin. 0 minimum (yükler tüm günlük) ve 1000 maksimum. Yük statik bir günlük gösterir ve kuyruk günlüğün son belirtilen satır sayısı ile otomatik güncelleştirme gösterir.", "last_log_lines": "Son günlük satırı sayısı", "load": "Yük", "tail": "Kuyruk" @@ -2278,6 +2316,9 @@ "para_migrate": "'Ayarları aktar' düğmesine bastığınız zaman Home Assistant tüm kartlarınıza ve görünümlerinize otomatik olarak kimlik atayabilir.", "para_no_id": "Bu öğenin bir kimliği yok. Lütfen 'ui-lovelace.yaml' dosyasında bu elemente bir kimlik ekleyin." }, + "move_card": { + "header": "Kartı taşımak için bir görünüm seçin" + }, "raw_editor": { "confirm_remove_config_text": "Lovelace kullanıcı arayüzü yapılandırmanızı kaldırırsanız, Lovelace kullanıcı arayüzü, görünümleriniz alanlarınız ve cihazlarınız otomatik olarak oluşturulacatır.", "confirm_remove_config_title": "Lovelace UI yapılandırmanızı kaldırmak istediğinizden emin misiniz? Lovelace kullanıcı arayüzü görünümlerinizi alanlarınız ve cihazlarınızla otomatik olarak oluşturacağız.", @@ -2303,6 +2344,10 @@ "save": "Kontrol altına al", "yaml_mode": "Bu gösterge tablosu için YAML modunu kullanıyorsunuz. Bunun anlamı, Lovelace yapılandırmanızı kullanıcı arayüzünden değiştiremezsiniz. Bu gösterge tablosunu kullanıcı arayüzünden yönetmek istiyorsanız, 'configuration: yaml' içindeki Lovelace yapılandırmanızdan 'mode: yaml' öğesini kaldırın." }, + "select_view": { + "dashboard_label": "Gösterge Paneli", + "header": "Bir görünüm seçin" + }, "suggest_card": { "add": "Lovelace kullanıcı arayüzüne ekle", "create_own": "Farklı kart seç", @@ -2500,13 +2545,16 @@ }, "page-onboarding": { "core-config": { - "button_detect": "Tespit", + "button_detect": "Algıla", "finish": "Sonraki", "intro": "Merhaba {name} , Home Assistant'a hoş geldin. Evini nasıl adlandırmak istersin?", - "location_name_default": "Evde" + "intro_location": "Nerede yaşadığınızı bilmek isteriz. Bu bilgiler, güneşe dayalı bilgilerin görüntülenmesine ve otomasyonların kurulmasına yardımcı olacaktır. Bu veriler asla ağınızın dışında paylaşılmaz.", + "intro_location_detect": "Harici bir hizmete tek seferlik talepte bulunarak bu bilgileri doldurmanıza yardımcı olabiliriz.", + "location_name_default": "Evim" }, "integration": { "finish": "Bitir", + "intro": "Cihazlar ve hizmetler, Home Asistant'ta entegrasyonlar olarak temsil edilir. Bunları şimdi kurabilir veya daha sonra yapılandırma ekranından yapabilirsiniz.", "more_integrations": "Daha fazla" }, "user": { @@ -2564,6 +2612,7 @@ "create_failed": "Erişim anahtarı oluşturulamadı.", "created_at": "{date} tarihinde oluşturuldu", "delete_failed": "Erişim anahtarı silinemedi.", + "description": "Komut dosyalarınızın Home Assistant örneğinizle etkileşime girmesine izin vermek için uzun ömürlü erişim jetonları oluşturun. Her bir jeton, oluşturulduktan sonra 10 yıl süreyle geçerli olacaktır. Aşağıdaki uzun ömürlü erişim jetonları şu anda aktif.", "empty_state": "Henüz uzun ömürlü erişim anahtarınız yok.", "header": "Uzun ömürlü erişim anahtarları", "last_used": "En son {date} tarihinde {location} konumundan kullanıldı", @@ -2583,7 +2632,7 @@ "confirm_disable": "{name} adlı öğeyi devre dışı bırakmak istediğinizden emin misiniz?", "disable": "Devre dışı bırak", "enable": "Etkinleştir", - "header": "Çoklu-faktör Kimlik Doğrulama Modülleri" + "header": "Çok Faktörlü Kimlik Doğrulama Modülleri" }, "push_notifications": { "description": "Bu cihaza bildirimler gönder", @@ -2605,14 +2654,22 @@ "token_title": "{clientId} için yenileme anahtarı" }, "suspend": { - "description": "5 dakika boyunca gizlendikten sonra sunucu bağlantısı kapatılsın mı?", + "description": "5 dakika boyunca aktif olmayınca sunucu ile bağlantı kapatılsın mı?", "header": "Bağlantıyı otomatik olarak kapat" }, "themes": { + "accent_color": "Vurgu rengi", + "dark_mode": { + "auto": "Otomatik", + "dark": "Karanlık", + "light": "Işık" + }, "dropdown_label": "Tema", "error_no_theme": "Kullanılabilir tema yok.", "header": "Tema", - "link_promo": "Temalar hakkında bilgi edinin" + "link_promo": "Temalar hakkında bilgi edinin", + "primary_color": "Birincil renk", + "reset": "Sıfırla" }, "vibrate": { "description": "Cihazları kontrol ederken bu cihazdaki titreşimi etkinleştirin veya devre dışı bırakın.", From dec1f99a5fbfdafb348d30fa0f7a03f84b0d5d9e Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 10 Aug 2020 09:36:01 +0200 Subject: [PATCH 08/38] Fix hassio panel dark mode (#6569) --- hassio/src/hassio-main.ts | 51 ++++++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index d20c690e30..7d55a23378 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -28,15 +28,7 @@ export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) { protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); - applyThemesOnElement( - this.parentElement, - this.hass.themes, - (atLeastVersion(this.hass.config.version, 0, 114) - ? this.hass.selectedTheme?.theme - : ((this.hass.selectedTheme as unknown) as string)) || - this.hass.themes.default_theme, - this.hass.selectedTheme - ); + this._applyTheme(); // Paulus - March 17, 2019 // We went to a single hass-toggle-menu event in HA 0.90. However, the @@ -73,6 +65,17 @@ export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) { makeDialogManager(this, this.shadowRoot!); } + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + const oldHass = changedProps.get("hass") as HomeAssistant | undefined; + if (!oldHass) { + return; + } + if (oldHass.themes !== this.hass.themes) { + this._applyTheme(); + } + } + protected render() { return html` `; } + + private _applyTheme() { + let themeName: string; + let options: Partial | undefined; + + if (atLeastVersion(this.hass.config.version, 0, 114)) { + themeName = + this.hass.selectedTheme?.theme || + (this.hass.themes.darkMode && this.hass.themes.default_dark_theme + ? this.hass.themes.default_dark_theme! + : this.hass.themes.default_theme); + + options = this.hass.selectedTheme; + if (themeName === "default" && options?.dark === undefined) { + options = { + ...this.hass.selectedTheme, + dark: this.hass.themes.darkMode, + }; + } + } else { + themeName = (this.hass.selectedTheme as unknown) as string; + } + + applyThemesOnElement( + this.parentElement, + this.hass.themes, + themeName, + options + ); + } } declare global { From 7f819f00204903a8c463a70f5e40bb6d599466b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 10 Aug 2020 16:23:14 +0200 Subject: [PATCH 09/38] Set min width (#6583) --- .../lovelace/editor/view-editor/hui-dialog-edit-view.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts index a03c42f826..cc5c9daaca 100644 --- a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts @@ -411,6 +411,12 @@ export class HuiDialogEditView extends LitElement { margin: 12px 16px; flex-wrap: wrap; } + + @media all and (min-width: 600px) { + ha-dialog { + --mdc-dialog-min-width: 600px; + } + } `, ]; } From 1eac9fa1cd05e31bcbaf81f59345cf117a4ceb60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 10 Aug 2020 16:42:55 +0200 Subject: [PATCH 10/38] Set header and tab color (#6582) --- src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts index cc5c9daaca..99a4022efc 100644 --- a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts @@ -342,6 +342,7 @@ export class HuiDialogEditView extends LitElement { css` h2 { display: block; + color: var(--primary-text-color); line-height: normal; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; @@ -380,6 +381,7 @@ export class HuiDialogEditView extends LitElement { } paper-tabs { --paper-tabs-selection-bar-color: var(--primary-color); + color: var(--primary-text-color); text-transform: uppercase; border-bottom: 1px solid rgba(0, 0, 0, 0.1); padding: 0 20px; From 16167bef07959d574cfad3f2e071191fa91cbc19 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Tue, 11 Aug 2020 00:32:11 +0000 Subject: [PATCH 11/38] [ci skip] Translation update --- translations/frontend/da.json | 2 +- translations/frontend/nb.json | 2 +- translations/frontend/pt-BR.json | 70 ++++++++++++++++++++++++++++-- translations/frontend/tr.json | 19 +++++--- translations/frontend/zh-Hant.json | 2 +- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/translations/frontend/da.json b/translations/frontend/da.json index 14550a224a..075b09ecb2 100644 --- a/translations/frontend/da.json +++ b/translations/frontend/da.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "Luk", - "configure_ui": "Konfigurer brugerflade", + "configure_ui": "Rediger betjeningspanel", "exit_edit_mode": "Afslut brugerflade-redigeringstilstand", "help": "Hjælp", "refresh": "Opdater", diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index b22415f52b..36496f4f21 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "Lukk", - "configure_ui": "Konfigurer brukergrensesnitt", + "configure_ui": "Rediger brukergrensesnitt", "exit_edit_mode": "Avslutt redigeringsmodus for brukergrensesnitt", "help": "Hjelp", "refresh": "Oppdater", diff --git a/translations/frontend/pt-BR.json b/translations/frontend/pt-BR.json index 8e3ba9cd45..7656f77073 100644 --- a/translations/frontend/pt-BR.json +++ b/translations/frontend/pt-BR.json @@ -725,6 +725,7 @@ "zha_device_info": { "buttons": { "add": "Adicionar dispositivos através deste dispositivo", + "clusters": "Gerenciar Grupos", "reconfigure": "Reconfigurar O Dispositivo", "remove": "Remover dispositivo", "zigbee_information": "Assinatura de dispositivo Zigbee" @@ -832,6 +833,15 @@ "name": "Açao", "type_select": "Tipo de acão", "type": { + "choose": { + "add_option": "Adicionar opção", + "conditions": "Condições", + "default": "Ações padrão", + "label": "Selecione", + "option": "Opção {number}", + "remove_option": "Remover opção", + "sequence": "Ações" + }, "condition": { "label": "Condição" }, @@ -851,6 +861,24 @@ "label": "Iniciar evento", "service_data": "Dados do Serviço" }, + "repeat": { + "label": "Repetir", + "sequence": "Ações", + "type_select": "Tipo de repetição", + "type": { + "count": { + "label": "Contagem" + }, + "until": { + "conditions": "Condições (até que...)", + "label": "Até que" + }, + "while": { + "conditions": "Condições (enquanto...)", + "label": "Enquanto" + } + } + }, "scene": { "label": "Ativar cena" }, @@ -1618,6 +1646,18 @@ "title": "", "topic": "tópico" }, + "ozw": { + "common": { + "node_id": "ID do Nó", + "ozw_instance": "Instância OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Falha no nó", + "stage": "Estágio", + "zwave_info": "Informações de Z-Wave" + } + }, "person": { "add_person": "Adicionar pessoa", "caption": "Pessoas", @@ -1807,7 +1847,8 @@ "name": "Nome", "system": "Sistema" } - } + }, + "users_privileges_note": "Grupos de Usuários ainda é um recurso experimental. O usuário será incapaz de administrar através da interface grática. Nós ainda estamos auditando todos os endponts da API de gerenciamento para se certificar que eles limitam o acesso para administradores da maneira correta." }, "zha": { "add_device_page": { @@ -1980,13 +2021,21 @@ "node_management": { "add_to_group": "Adicionar ao Grupo", "entities": "Entidades deste nó", + "entity_info": "Informações da Entidade", "exclude_entity": "Excluir esta entidade do Home Assistant", "group": "Grupo", "header": "Gerenciamento de nó Z-Wave", + "introduction": "Executar comandos Z-Wave que afetam um único nó. Seleciona um nó para ver a lista de comandos disponíveis", + "max_associations": "Máximo de Associações", "node_group_associations": "Associações de grupos de nós", "node_protection": "Proteção dos nós", + "node_to_control": "Nó para controlar", "nodes": "Nós", + "nodes_hint": "Selecione um nó para ver opções específicas", + "nodes_in_group": "Outros nós neste grupo", + "pooling_intensity": "Frequência da consulta", "protection": "Proteção", + "remove_broadcast": "Remover Broadcast", "remove_from_group": "Remover do Grupo", "set_protection": "Definir proteção" }, @@ -2342,7 +2391,7 @@ "show_code_editor": "Mostrar Editor de Código", "show_visual_editor": "Mostrar Editor Visual", "toggle_editor": "Alternar Editor", - "typed_header": "Configuração de cartão {type}", + "typed_header": "Configuração do cartão {type}", "unsaved_changes": "Você tem alterações não salvas" }, "edit_lovelace": { @@ -2377,6 +2426,9 @@ "para_migrate": "O Home Assistant pode adicionar IDs a todos os seus cards e visualizações automaticamente clicando no botão 'Migrar configuração'.", "para_no_id": "Este elemento não possui um ID. Por favor adicione um ID a este elemento em 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Selecione uma tela para onde mover este cartão" + }, "raw_editor": { "confirm_remove_config_text": "Geraremos automaticamente suas visualizações da interface do usuário do Lovelace com suas áreas e dispositivos se você remover a configuração da interface do usuário do Lovelace.", "confirm_remove_config_title": "Tem certeza de que deseja remover a configuração da interface Lovelace? Geraremos automaticamente visualizações da interface Lovelace com suas áreas e dispositivos.", @@ -2404,6 +2456,10 @@ "yaml_control": "Para assumir o controle no modo YAML, crie um arquivo YAML com o nome que você especificou na sua configuração para este painel ou arquivo padrão 'ui-lovelace.yaml'.", "yaml_mode": "Você está usando o modo YAML para este painel, o que significa que não é possível alterar a configuração do Lovelace na interface. Se você deseja gerenciar esse painel na interface do usuário, remova 'mode: yaml' da configuração do Lovelace em 'configuration.yaml.'" }, + "select_view": { + "dashboard_label": "Painel de controle", + "header": "Selecione uma tela" + }, "suggest_card": { "add": "Adicionar a UI do Lovelace", "create_own": "Escolha cartão diferente", @@ -2721,10 +2777,18 @@ "header": "Fechar a conexão automaticamente" }, "themes": { + "accent_color": "Cor de detalhe", + "dark_mode": { + "auto": "Automático", + "dark": "Escuro", + "light": "Claro" + }, "dropdown_label": "Tema", "error_no_theme": "Não há temas disponíveis.", "header": "Tema", - "link_promo": "Aprenda sobre temas" + "link_promo": "Aprenda sobre temas", + "primary_color": "Cor Principal", + "reset": "Redefinir" }, "vibrate": { "description": "Ative ou desative a vibração neste dispositivo ao controlar dispositivos.", diff --git a/translations/frontend/tr.json b/translations/frontend/tr.json index 0c2c4831f9..1d11c4e2d7 100644 --- a/translations/frontend/tr.json +++ b/translations/frontend/tr.json @@ -785,7 +785,7 @@ "link_profile_page": "profil sayfanız" }, "areas": { - "caption": "Alanları", + "caption": "Alanlar", "data_table": { "area": "Alan", "devices": "Cihazlar" @@ -1192,7 +1192,9 @@ "email": "E-posta", "email_error_msg": "Geçersiz e-posta", "forgot_password": "Parolanızı mı unuttunuz?", - "introduction2": "Bu hizmet ortağımız tarafından yürütülüyor", + "introduction": "Home Assistant Cloud, evden uzaktayken örneğinize güvenli bir uzaktan bağlantı sağlar. Ayrıca diğer bulut hizmetlerine bağlanmanıza olanak tanır: Amazon Alexa ve Google Assistant.", + "introduction2": "Bu hizmet ortağımız ", + "introduction2a": "tarafından verilmektedir, Home Assistant ve Hass.io kurucuları tarafından kurulan bir şirket.", "introduction3": "Home Assistant Cloud, bir aylık ücretsiz deneme sürümüne sahip bir abonelik hizmetidir. Ödeme bilgisi gerekmez.", "learn_more_link": "Home Assistant Cloud hakkında daha fazla bilgi edin", "password": "Parola", @@ -1214,8 +1216,8 @@ "headline": "Ücretsiz denemenizi başlatın", "information": "Home Assistant Cloud ile bir aylık ücretsiz denemenizi başlatmak için bir hesap oluşturun. Ödeme bilgisi gerekmez.", "information2": "Deneme, aşağıdakiler de dahil olmak üzere Home Assistant Cloud'un tüm avantajlarına erişmenizi sağlayacaktır:", - "information3": "Bu hizmet ortağımız tarafından yürütülüyor", - "information3a": ", Home Assistant ve Hass.io'nun kurucuları tarafından kurulmuş bir şirkettir.", + "information3": "Bu hizmet ortağımız ", + "information3a": "tarafından verilmektedir, Home Assistant ve Hass.io kurucuları tarafından kurulan bir şirket.", "information4": "Bir hesap kaydederek aşağıdaki şartlar ve koşulları kabul etmiş olursunuz.", "link_privacy_policy": "Gizlilik Politikası", "link_terms_conditions": "Şartlar ve koşullar", @@ -1624,9 +1626,10 @@ "name": "Ad", "name_error_msg": "Isim gereklidir", "new_person": "Yeni kişi", - "update": "Güncelleme" + "no_device_tracker_available_intro": "Bir kişinin varlığını gösteren aygıtlarınız olduğunda, bunları buradaki bir kişiye atayabilirsiniz. Entegrasyonlar sayfasından bir varlık algılama entegrasyonu ekleyerek ilk cihazınızı ekleyebilirsiniz.", + "update": "Güncelle" }, - "introduction": "Burada Home Assistant ilgi her kişi tanımlayabilirsiniz.", + "introduction": "Burada Home Assistant ile ilgili her kişiyi tanımlayabilirsiniz.", "no_persons_created_yet": "Henüz herhangi bir kişi oluşturmadığın gibi görünüyor.", "note_about_persons_configured_in_yaml": "Not: configuration.yaml aracılığıyla yapılandırılan kişiler UI aracılığıyla düzenlenemez." }, @@ -1996,7 +1999,7 @@ "available_events": "Mevcut Etkinlikler", "count_listeners": " ({count} dinleyiciler)", "data": "Olay Verileri (YAML, isteğe bağlı)", - "description": "Etkinlik otobüsünde bir etkinlik başlat.", + "description": "Olay veri yolunda bir olay tetikleyin.", "documentation": "Olaylar Dökümantasyonu.", "fire_event": "Olayı Çalıştır", "listen_to_events": "Olayları dinleyin", @@ -2014,6 +2017,7 @@ "column_example": "Örnek", "column_parameter": "Parametre", "data": "Servis Verileri (YAML, isteğe bağlı)", + "description": "Servisler geliştirici araçı, Home Assistant'taki mevcut tüm hizmetleri aramanızı sağlar.", "fill_example_data": "Örnek Verileri Doldur", "no_description": "Açıklama mevcut değil", "no_parameters": "Bu servis parametre almaz.", @@ -2137,6 +2141,7 @@ "entities": { "description": "Varlıklar kartı en yaygın kart türüdür. Öğeleri listeler halinde gruplandırır.", "name": "Varlıklar", + "show_header_toggle": "Başlık Değiştirme Gösterilsin mi?", "toggle": "Varlıklarageçiş." }, "entity-filter": { diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index d0be0db91b..adc72e651f 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "關閉", - "configure_ui": "介面設定", + "configure_ui": "編輯主面板", "exit_edit_mode": "退出 UI 編輯模式", "help": "說明", "refresh": "更新", From 271eb614cd31d2bc24107cdc41b64b9adf64d05c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 11 Aug 2020 13:22:46 +0200 Subject: [PATCH 12/38] Use primary-background-color when it exists (#6594) --- src/html/index.html.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/html/index.html.template b/src/html/index.html.template index fe4271c0fb..5ec5dd1dc1 100644 --- a/src/html/index.html.template +++ b/src/html/index.html.template @@ -48,7 +48,7 @@ } @media (prefers-color-scheme: dark) { html { - background-color: #111111; + background-color: var(--primary-background-color, #111111); } #ha-init-skeleton::before { background-color: #1c1c1c; From 283b134d84ae2858115c77c908b53cd6a1fe8680 Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Tue, 11 Aug 2020 11:57:03 +0000 Subject: [PATCH 13/38] Bumped version to 20200811.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 834ffe3aab..289a8db76f 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20200807.1", + version="20200811.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", From 41b613a2d7c20eff5cced16c9eda86af39a44421 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Tue, 11 Aug 2020 14:01:20 +0200 Subject: [PATCH 14/38] Fix wrapping for diagnostics row (#6595) --- hassio/src/system/hassio-supervisor-info.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 7423da51a8..0452bd5188 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -65,7 +65,7 @@ class HassioSupervisorInfo extends LitElement { Share Diagnostics - +
Share crash reports and diagnostic information. - +

- The data does not include any private/sensetive information and you can + The data does not include any private/sensitive information and you can disable this in settings at any time you want.`, }); } From 746844dfc85469a18acee8bc399877add86d23b0 Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Tue, 11 Aug 2020 12:15:08 +0000 Subject: [PATCH 15/38] Only show diagnostics if healthy --- hassio/src/system/hassio-supervisor-info.ts | 38 +++++++++++---------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 0452bd5188..71b21423e0 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -61,24 +61,26 @@ class HassioSupervisorInfo extends LitElement {
- - - Share Diagnostics - -
- Share crash reports and diagnostic information. - -
- -
+ ${this.supervisorInfo?.healthy + ? html` + + Share Diagnostics + +
+ Share crash reports and diagnostic information. + +
+ +
` + : ""}
${this._errors ? html`
Error: ${this._errors}
` From 2bb64e9e2fd5092f4d31f7308e1264d0577c69a4 Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Tue, 11 Aug 2020 12:28:35 +0000 Subject: [PATCH 16/38] Use supported instead --- hassio/src/system/hassio-supervisor-info.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 71b21423e0..189738ea09 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -61,7 +61,7 @@ class HassioSupervisorInfo extends LitElement {
- ${this.supervisorInfo?.healthy + ${this.supervisorInfo?.supported ? html` Share Diagnostics From 96986164a43e06924a82669f5734a913379393a2 Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Tue, 11 Aug 2020 14:12:38 +0000 Subject: [PATCH 17/38] Show error if not supported --- hassio/src/system/hassio-supervisor-info.ts | 23 +++++++++++++++------ hassio/src/system/hassio-system.ts | 1 + 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/hassio/src/system/hassio-supervisor-info.ts b/hassio/src/system/hassio-supervisor-info.ts index 189738ea09..b76f791c4d 100644 --- a/hassio/src/system/hassio-supervisor-info.ts +++ b/hassio/src/system/hassio-supervisor-info.ts @@ -12,6 +12,7 @@ import { import { fireEvent } from "../../../src/common/dom/fire_event"; import "../../../src/components/buttons/ha-call-api-button"; import "../../../src/components/ha-card"; +import { HassioHostInfo as HassioHostInfoType } from "../../../src/data/hassio/host"; import { HassioSupervisorInfo as HassioSupervisorInfoType, setSupervisorOption, @@ -33,6 +34,8 @@ class HassioSupervisorInfo extends LitElement { @property() public supervisorInfo!: HassioSupervisorInfoType; + @property() public hostInfo!: HassioHostInfoType; + @internalProperty() private _errors?: string; public render(): TemplateResult | void { @@ -80,10 +83,22 @@ class HassioSupervisorInfo extends LitElement { @change=${this._toggleDiagnostics} > ` - : ""} + : html`
+ You are running an unsupported installation. + Learn More +
`}
${this._errors - ? html`
Error: ${this._errors}
` + ? html`
Error: ${this._errors}
` : ""}
@@ -145,10 +160,6 @@ class HassioSupervisorInfo extends LitElement { .info td:nth-child(2) { text-align: right; } - .errors { - color: var(--error-color); - margin-top: 16px; - } ha-settings-row { padding: 0; } diff --git a/hassio/src/system/hassio-system.ts b/hassio/src/system/hassio-system.ts index 00a304ed03..3a52347a08 100644 --- a/hassio/src/system/hassio-system.ts +++ b/hassio/src/system/hassio-system.ts @@ -56,6 +56,7 @@ class HassioSystem extends LitElement {
Date: Wed, 12 Aug 2020 13:15:24 +0000 Subject: [PATCH 18/38] Use default as fallback theme for older versions --- hassio/src/hassio-main.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index 7d55a23378..b6f485b7d9 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -106,9 +106,13 @@ export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) { }; } } else { - themeName = (this.hass.selectedTheme as unknown) as string; + themeName = + ((this.hass.selectedTheme as unknown) as string) || + this.hass.themes.default_theme; } + console.log(themeName); + applyThemesOnElement( this.parentElement, this.hass.themes, From d09f74d30f49b224fd7e04ff8683fff71ae3f448 Mon Sep 17 00:00:00 2001 From: Ludeeus Date: Wed, 12 Aug 2020 13:15:39 +0000 Subject: [PATCH 19/38] console.die --- hassio/src/hassio-main.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index b6f485b7d9..ccabb2e426 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -111,8 +111,6 @@ export class HassioMain extends urlSyncMixin(ProvideHassLitMixin(LitElement)) { this.hass.themes.default_theme; } - console.log(themeName); - applyThemesOnElement( this.parentElement, this.hass.themes, From 80fc37724b7878be301429fd5f323335b1d1a72a Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Thu, 13 Aug 2020 00:32:21 +0000 Subject: [PATCH 20/38] [ci skip] Translation update --- translations/frontend/it.json | 42 ++++++++++++++++++++++++++++++++++- translations/frontend/ja.json | 25 +++++++++++++++++++-- translations/frontend/nn.json | 4 ++-- 3 files changed, 66 insertions(+), 5 deletions(-) diff --git a/translations/frontend/it.json b/translations/frontend/it.json index 2840cc38de..d22f43449c 100644 --- a/translations/frontend/it.json +++ b/translations/frontend/it.json @@ -834,9 +834,12 @@ "type_select": "Tipo di azione", "type": { "choose": { + "add_option": "Aggiungi opzione", "conditions": "Condizioni", "default": "Azione predefinita", "label": "Scegli", + "option": "Opzione {number}", + "remove_option": "Rimuovi opzione", "sequence": "Azioni" }, "condition": { @@ -858,6 +861,24 @@ "label": "Attiva Evento", "service_data": "Dati del servizio" }, + "repeat": { + "label": "Ripetere", + "sequence": "Azioni", + "type_select": "Tipo \"ripetizione\"", + "type": { + "count": { + "label": "Conteggio" + }, + "until": { + "conditions": "Condizioni \"fino a\"", + "label": "Fino a" + }, + "while": { + "conditions": "Condizioni \"mentre\"", + "label": "Mentre" + } + } + }, "scene": { "label": "Attivare la scena" }, @@ -1625,6 +1646,18 @@ "title": "MQTT", "topic": "argomento" }, + "ozw": { + "common": { + "node_id": "ID del nodo", + "ozw_instance": "Istanza OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Nodo non riuscito", + "stage": "Fase", + "zwave_info": "Informazioni Z-Wave" + } + }, "person": { "add_person": "Aggiungi persona", "caption": "Persone", @@ -2393,6 +2426,9 @@ "para_migrate": "Home Assistant può aggiungere automaticamente gli ID a tutte le tue schede e viste in maniera automatica premendo il pulsante \"Esporta Configurazione\".", "para_no_id": "Questo elemento non ha un ID. Aggiungi un ID a questo elemento in 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Scegli una visualizzazione in cui spostare la scheda" + }, "raw_editor": { "confirm_remove_config_text": "Genereremo automaticamente le tue viste dell'Interfaccia utente di Lovelace con le tue aree e dispositivi se rimuovi la tua configurazione dell'interfaccia utente di Lovelace.", "confirm_remove_config_title": "Sei sicuro di voler rimuovere la tua configurazione dell'interfaccia utente di Lovelace? Genereremo automaticamente le tue viste Lovelace con le tue aree e dispositivi.", @@ -2420,6 +2456,10 @@ "yaml_control": "Per assumere il controllo in modalità YAML, creare un file YAML con il nome specificato nella tua configurazione per questa plancia, o il predefinito 'ui-lovelace.yaml'.", "yaml_mode": "Questa plancia sta utilizzando la modalità YAML, il che significa che non è possibile modificare la configurazione di Lovelace dall'Interfaccia Utente. Se volete gestire questa plancia dall'Interfaccia Utente, rimuovere 'mode: yaml' dalla configurazione di Lovelace in 'configuration.yaml'." }, + "select_view": { + "dashboard_label": "Plancia", + "header": "Scegliere una visualizzazione" + }, "suggest_card": { "add": "Aggiungi all'interfaccia utente di Lovelace", "create_own": "Scegliere una scheda diversa", @@ -2435,7 +2475,7 @@ }, "menu": { "close": "Chiudi", - "configure_ui": "Configurare l'Interfaccia Utente", + "configure_ui": "Modifica la Plancia", "exit_edit_mode": "Esci dalla modalità di modifica dell'Interfaccia Utente", "help": "Aiuto", "refresh": "Aggiorna", diff --git a/translations/frontend/ja.json b/translations/frontend/ja.json index 7a74c95fd4..0438a1bf5b 100644 --- a/translations/frontend/ja.json +++ b/translations/frontend/ja.json @@ -512,7 +512,8 @@ }, "login-form": { "log_in": "ログイン", - "password": "パスワード" + "password": "パスワード", + "remember": "覚えて" }, "notification_drawer": { "close": "閉じる", @@ -654,6 +655,7 @@ }, "state": { "from": "変化前", + "label": "状態", "to": "変化後" }, "sun": { @@ -993,6 +995,17 @@ "title": "MQTT", "topic": "トピック" }, + "ozw": { + "common": { + "node_id": "ノードID", + "ozw_instance": "OpenZWaveインスタンス" + }, + "device_info": { + "node_failed": "ノードが失敗しました", + "stage": "段階", + "zwave_info": "Z-Wave情報" + } + }, "person": { "caption": "人", "description": "Home Assistant を追跡している人の管理。", @@ -1331,6 +1344,9 @@ "menu": { "open": "Lovelace メニューを開く" }, + "move_card": { + "header": "カードを移動するビューを選択してください" + }, "raw_editor": { "confirm_unsaved_changes": "未保存の変更があります、終了してもよろしいですか?", "confirm_unsaved_comments": "コンフィグレーションはコメントが含まれています、これらは保存されません。本当に続けますか?", @@ -1340,6 +1356,10 @@ }, "save_config": { "close": "閉じる" + }, + "select_view": { + "dashboard_label": "ダッシュボード", + "header": "ビューに移動" } }, "menu": { @@ -1363,7 +1383,8 @@ "mailbox": { "delete_button": "削除", "delete_prompt": "このメッセージを削除しますか?", - "empty": "メッセージはありません" + "empty": "メッセージはありません", + "playback_title": "メッセージの再生" }, "page-authorize": { "abort_intro": "ログインが中止されました", diff --git a/translations/frontend/nn.json b/translations/frontend/nn.json index 3e8e390309..69b3e297fb 100644 --- a/translations/frontend/nn.json +++ b/translations/frontend/nn.json @@ -354,7 +354,7 @@ "climate": { "aux_heat": "Aux-varme", "away_mode": "Bortemodus", - "currently": "Akkuratt no", + "currently": "Akkurat no", "fan_mode": "Viftemodus", "on_off": "På / av", "operation": "Operasjon", @@ -953,7 +953,7 @@ "description": "Oversikt over alle kjende oppføringar.", "picker": { "header": "Oppføringsregisteret", - "introduction": "Home Assistant har eit register over alle oppføringane den nokon gang har sett som kan unikt identifiserast. Kvar av desse oppføringane har ein eigen oppføringsidentifikasjon som er reservert for akkuratt denne oppføringa.", + "introduction": "Home Assistant har eit register over alle oppføringane den nokon gang har sett som kan unikt identifiserast. Kvar av desse oppføringane har ein eigen oppføringsidentifikasjon som er reservert for akkurat denne oppføringa.", "introduction2": "Bruk oppføringsregisteret til å skrive over namn, endre oppføringsidentifikasjonane eller fjerne oppføringar frå Home Assistant. Merk deg at å fjerne oppføringa i oppføringregisteret ikkje fjernar sjølve oppføringa. For å gjere dette, gå vidare inn på linken under og fjern oppføringa i integrasjonssida." } }, From 9c6dac8180cd9857112a2c4a010bc853ede00810 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Fri, 14 Aug 2020 00:32:15 +0000 Subject: [PATCH 21/38] [ci skip] Translation update --- translations/frontend/de.json | 5 + translations/frontend/es.json | 2 +- translations/frontend/et.json | 145 +++++++++++++++++++++++-- translations/frontend/nl.json | 45 +++++++- translations/frontend/nn.json | 2 +- translations/frontend/sk.json | 168 +++++++++++++++++++++++++++-- translations/frontend/zh-Hans.json | 2 +- 7 files changed, 348 insertions(+), 21 deletions(-) diff --git a/translations/frontend/de.json b/translations/frontend/de.json index 1d2422085d..ae49612394 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -1619,6 +1619,11 @@ "title": "MQTT", "topic": "Topic" }, + "ozw": { + "device_info": { + "zwave_info": "Z-wave Infos" + } + }, "person": { "add_person": "Person hinzufügen", "caption": "Personen", diff --git a/translations/frontend/es.json b/translations/frontend/es.json index f5b4dabc25..6777ea2763 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -2088,7 +2088,7 @@ "description": "Disparar un evento en el bus de eventos.", "documentation": "Documentación de eventos.", "event_fired": "Evento {name} disparado", - "fire_event": "Disparar evento", + "fire_event": "Lanzar evento", "listen_to_events": "Escuchar eventos", "listening_to": "Escuchando", "notification_event_fired": "¡Evento {tipe} disparado con éxito!", diff --git a/translations/frontend/et.json b/translations/frontend/et.json index d34f2027d8..51e3f2f620 100644 --- a/translations/frontend/et.json +++ b/translations/frontend/et.json @@ -386,6 +386,9 @@ "reverse": "Tagurpidi", "speed": "Kiirus" }, + "humidifier": { + "target_humidity_entity": "Soovitud niiskusemäär" + }, "light": { "brightness": "Heledus", "color_temperature": "Värvustemperatuur", @@ -471,8 +474,12 @@ "cancel": "Loobu", "close": "Sulge", "loading": "Laadimine", + "menu": "Menüü", "no": "Ei", + "previous": "Eelmine", + "refresh": "Värskenda", "save": "Salvesta", + "successfully_deleted": "Edukalt kustutatud", "successfully_saved": "Edukalt salvestatud", "yes": "Jah" }, @@ -544,7 +551,7 @@ "dismiss": "Loobu", "editor": { "confirm_delete": "Oled kindel, et soovid selle kirje kustutada?", - "delete": "KUSTUTA", + "delete": "Kustuta", "enabled_cause": "Keelatud, sest {cause}.", "enabled_description": "Keelatud olemeid ei lisata Home Assistant'i.", "enabled_label": "Luba olem", @@ -552,8 +559,9 @@ "name": "Nime muutmine", "note": "Märkus: see ei pruugi veel töötada kõigi sidumistega.", "unavailable": "See olem pole praegu saadaval.", - "update": "UUENDA" + "update": "Uuenda" }, + "no_unique_id": "Sellel olemil pole unikaalset ID-d, seetõttu ei saa selle seadeid kasutajaliidesest hallata.", "related": "Seotud", "settings": "Seaded" }, @@ -562,6 +570,28 @@ "default_confirmation_title": "Oled sa kindel?", "ok": "OK" }, + "helper_settings": { + "generic": { + "name": "Nimi" + }, + "input_datetime": { + "date": "Kuupäev", + "datetime": "Kuupäev ja kellaaeg", + "time": "Aeg" + }, + "input_number": { + "step": "Sammu suurus", + "unit_of_measurement": "Mõõtühik" + }, + "input_select": { + "add": "Lisa" + }, + "input_text": { + "max": "Maksimaalne pikkus", + "min": "Minimaalne pikkus", + "password": "Salasõna" + } + }, "more_info_control": { "dismiss": "Loobu dialoogist", "edit": "Muuda olemit", @@ -658,23 +688,35 @@ }, "notification_toast": { "connection_lost": "Ühendus kadunud. Taasühendamine...", - "service_call_failed": "Teenuse {service} väljakutsumine ebaõnnestus." + "service_call_failed": "Teenuse {service} väljakutsumine ebaõnnestus.", + "started": "Koduabiline on käivitunud!" }, "panel": { + "calendar": { + "my_calendars": "Minu kalendrid", + "today": "Täna" + }, "config": { "areas": { "caption": "Alade register", + "delete": { + "confirmation_title": "Oled kindel, et soovid selle ala kustutada?" + }, "description": "Ülevaade kõikidest oma kodu aladest.", "editor": { + "area_id": "Piirkonna ID", "create": "LOO", + "default_name": "Uus ala", "delete": "KUSTUTA", "update": "UUENDA" }, "picker": { + "create_area": "LOO ALA", "header": "Alade register", "integrations_page": "Sidumiste leht", "introduction": "Alasid kasutatakse seadmete paiknemise korraldamiseks. Seda teavet kasutatakse läbivalt kasutajaliidese, lubade ja teiste süsteemidega sidumise korraldamisel.", - "introduction2": "Seadmete paigutamiseks alale mine alloleva lingi kaudu sidumiste lehele ja seejärel klõpsa seadme kaartideni jõudmiseks seadistatud sidumisel." + "introduction2": "Seadmete paigutamiseks alale mine alloleva lingi kaudu sidumiste lehele ja seejärel klõpsa seadme kaartideni jõudmiseks seadistatud sidumisel.", + "no_areas": "Paistab, et sul pole veel alasid!" } }, "automation": { @@ -710,6 +752,9 @@ "label": "Vallanda sündmus", "service_data": "Teenuse andmed" }, + "repeat": { + "label": "Korda" + }, "scene": { "label": "Aktiveeri stseen" }, @@ -798,6 +843,9 @@ "introduction": "Kasuta oma kodule elu sisse puhumiseks automatiseeringuid.", "load_error_not_editable": "Ainult automations.yaml failis asuvad automatiseeringud on muudetavad.", "load_error_unknown": "Viga automatiseeringu laadimisel ({err_no}).", + "modes": { + "parallel": "Paralleelselt" + }, "save": "Salvesta", "triggers": { "add": "Lisa päästik", @@ -973,8 +1021,11 @@ "webhook_for": "Veebihaak {name} jaoks" }, "forgot_password": { + "check_your_email": "Parooli lähtestamise kohta saate juhiseid oma e-posti aadressilt.", "email": "E-post", "email_error_msg": "Vigane meiliaadress", + "instructions": "Sisestage oma e-posti aadress ja me saadame teile lingi parooli lähtestamiseks.", + "send_reset_email": "Saatke lähtestamismeil", "subtitle": "Unustasid oma salasõna", "title": "Unustasid salasõna" }, @@ -987,6 +1038,7 @@ "title": "Google Assistant" }, "login": { + "alert_email_confirm_necessary": "Enne sisselogimist peate oma e-posti aadressi kinnitama.", "alert_password_change_required": "Enne sisselogimist pead parooli muutma.", "dismiss": "Loobu", "email": "E-post", @@ -1001,6 +1053,7 @@ "trial_info": "Makseteavet pole vaja" }, "register": { + "account_created": "Konto loodud! Konto aktiveerimise kohta saate juhiseid oma e-posti aadressilt.", "create_account": "Loo konto", "email_address": "E-posti aadress", "email_error_msg": "Vigane meiliaadress", @@ -1013,7 +1066,8 @@ "password": "Salasõna", "password_error_msg": "Salasõnad on vähemalt 8 tähemärki", "resend_confirm_email": "Saada kinnitusmeil uuesti", - "start_trial": "Alusta proovimist" + "start_trial": "Alusta proovimist", + "title": "Loo konto" } }, "common": { @@ -1074,6 +1128,7 @@ } }, "caption": "Seadmed", + "confirm_delete": "Oled kindel, et soovid selle seadme kustutada?", "confirm_rename_entity_ids": "Kas soovid ka oma olemite ID-d ümber nimetada?", "data_table": { "area": "Ala", @@ -1083,7 +1138,9 @@ "manufacturer": "Tootja", "model": "Mudel" }, + "delete": "Kustuta", "description": "Halda ühendatud seadmeid", + "device_info": "Seadme info", "device_not_found": "Seadet ei leitud.", "entities": { "add_entities_lovelace": "Lisa Lovelace'i", @@ -1168,9 +1225,11 @@ "caption": "Sidumised", "config_entry": { "area": "alas {area}", + "delete": "Kustuta", "delete_button": "Kustuta {integration}", "delete_confirm": "Oled kindel, et soovid selle sidumise kustutada?", "device_unavailable": "seade pole saadaval", + "documentation": "Vaata dokumentatsiooni", "entity_unavailable": "olem pole saadaval", "firmware": "Püsivara: {version}", "hub": "Ühendatud", @@ -1215,6 +1274,7 @@ }, "introduction": "Siin saab seadistada oma komponente ja Home Assistant'i. Mitte kõike ei saa veel kasutajaliidese kaudu seadistada, kuid me töötame selle nimel.", "logs": { + "caption": "Logid", "clear": "Puhasta", "description": "Home Assistanti logid", "details": "Logi üksikasjad ({level})", @@ -1225,7 +1285,26 @@ "refresh": "Värskenda", "title": "Logid" }, + "lovelace": { + "dashboards": { + "detail": { + "dismiss": "Sulge", + "title": "Pealkiri" + }, + "picker": { + "open": "Ava" + } + }, + "resources": { + "detail": { + "delete": "Kustuta", + "update": "Uuenda" + }, + "refresh_header": "Kas soovite värskendada?" + } + }, "mqtt": { + "button": "Seadista", "description_listen": "Kuula teemat", "listening_to": "Kuulamas", "publish": "Avalda", @@ -1274,6 +1353,7 @@ "header": "Olemid", "without_device": "Olemid ilma seadmeta" }, + "icon": "Ikoon", "load_error_not_editable": "Ainult scenes.yaml failis asuvad stseenid on muudetavad.", "load_error_unknown": "Viga stseeni laadimisel ({err_no}).", "name": "Nimi", @@ -1302,7 +1382,12 @@ "delete_confirm": "Oled kindel, et soovid selle skripti kustutada?", "delete_script": "Kustuta skript", "header": "Skript: {name}", + "icon": "Ikoon", + "id_already_exists": "See ID on juba olemas", "load_error_not_editable": "Ainult scripts.yaml failis asuvad skriptid on muudetavad.", + "max": { + "queued": "Järjekorra pikkus" + }, "sequence": "Jada" }, "picker": { @@ -1369,7 +1454,14 @@ "id": "ID", "owner": "Omanik", "system_generated": "Süsteemi genereeritud", - "unnamed_user": "Nimetu kasutaja" + "unnamed_user": "Nimetu kasutaja", + "update_user": "Uuenda" + }, + "picker": { + "headers": { + "group": "Grupp", + "system": "Süsteem" + } } }, "zha": { @@ -1440,6 +1532,9 @@ "header": "Võrgu haldamine", "introduction": "Kogu võrku mõjutavad käsud" }, + "network": { + "caption": "Võrk" + }, "node_management": { "header": "Seadme haldus" }, @@ -1507,6 +1602,10 @@ "set_wakeup": "Määra ärkamise intervall", "true": "Tõene" }, + "node_management": { + "group": "Grupp", + "protection": "Kaitse" + }, "ozw_log": { "header": "OZW logi" }, @@ -1585,11 +1684,23 @@ }, "history": { "period": "Periood", + "ranges": { + "last_week": "Eelmine nädal", + "this_week": "See nädal", + "today": "Täna", + "yesterday": "Eile" + }, "showing_entries": "Näitan kuupäeva" }, "logbook": { "entries_not_found": "Logiraamatu kandeid ei leitud.", "period": "Periood", + "ranges": { + "last_week": "Eelmine nädal", + "this_week": "See nädal", + "today": "Täna", + "yesterday": "Eile" + }, "showing_entries": "Näitan kuupäeva" }, "lovelace": { @@ -1654,6 +1765,7 @@ "generic": { "aspect_ratio": "Proportsioonid", "camera_image": "Kaamera olem", + "camera_view": "Kaamera vaade", "entities": "Olemid", "entity": "Olem", "icon": "Ikoon", @@ -1680,6 +1792,9 @@ "horizontal-stack": { "name": "Horisontaalne pinu" }, + "humidifier": { + "name": "Niisutaja" + }, "iframe": { "name": "iFrame" }, @@ -1711,6 +1826,7 @@ "name": "Taime olek" }, "sensor": { + "graph_type": "Graafiku tüüp", "name": "Andur" }, "shopping-list": { @@ -1736,7 +1852,8 @@ "pick_card": "Vali kaart, mida soovid lisada.", "show_code_editor": "Kuva koodiredaktor", "show_visual_editor": "Kuva visuaalne redaktor", - "toggle_editor": "Lülita redaktor sisse/välja" + "toggle_editor": "Lülita redaktor sisse/välja", + "typed_header": "Kaardi seadistamine" }, "edit_lovelace": { "edit_title": "Muuda pealkirja", @@ -1752,7 +1869,8 @@ "move_left": "Liiguta vaadet vasakule", "move_right": "Liiguta vaadet paremale", "tab_badges": "Märgid", - "tab_settings": "Seaded" + "tab_settings": "Seaded", + "tab_visibility": "Nähtavus" }, "header": "Muuda kasutajaliidest", "menu": { @@ -1776,6 +1894,7 @@ }, "save_config": { "cancel": "Ära pane tähele", + "close": "Sulge", "header": "Võta Lovelace kasutajaliides oma kontrolli alla", "para": "Vaikimisi hoolitseb kasutajaliidese eest Home Assistant, värskendades seda, kui saadaval on uued olemid või Lovelace komponendid. Kui võtad kontrolli üle, ei tee me sinu jaoks enam automaatselt muudatusi.", "para_sure": "Oled kindel, et soovid kasutajaliidese oma kontrolli alla võtta?", @@ -1785,6 +1904,11 @@ "add": "Lisa Lovelace'i kasutajaliidesesse", "create_own": "Vali teine kaart", "header": "Lõime sulle ettepaneku" + }, + "view": { + "panel_mode": { + "warning_multiple_cards": "See vaade koosneb rohkem kui ühest kaardist, aga paneeli vaade saab näidata ainult ühte kaarti" + } } }, "menu": { @@ -1803,7 +1927,8 @@ "title": "Kasutamata olemid" }, "views": { - "confirm_delete": "Oled kindel, et soovid selle vaate kustutada?" + "confirm_delete": "Oled kindel, et soovid selle vaate kustutada?", + "confirm_delete_existing_cards": "Selle vaate kustutamisel eemaldatakse ka kaardid" }, "warning": { "entity_non_numeric": "Olem on mittenumbriline: {entity}", @@ -1893,6 +2018,7 @@ }, "trusted_networks": { "abort": { + "not_allowed": "Sinu arvuti ei ole lubatute nimekirjas.", "not_whitelisted": "Sinu arvuti ei ole lubatute nimekirjas." }, "step": { @@ -1905,6 +2031,7 @@ } } }, + "start_over": "Alusta uuesti", "unknown_error": "Midagi läks valesti", "working": "Palun oota" }, diff --git a/translations/frontend/nl.json b/translations/frontend/nl.json index 5cbb821fbe..65260bfdb9 100644 --- a/translations/frontend/nl.json +++ b/translations/frontend/nl.json @@ -836,7 +836,9 @@ "choose": { "add_option": "Optie toevoegen", "conditions": "Voorwaarden", + "default": "Standaardacties", "label": "Kies", + "option": "Optie {number}", "remove_option": "Verwijder optie", "sequence": "Acties" }, @@ -859,6 +861,24 @@ "label": "Gebeurtenis uitvoeren", "service_data": "Service data" }, + "repeat": { + "label": "Herhaling", + "sequence": "Acties", + "type_select": "Herhaal-type", + "type": { + "count": { + "label": "Telling" + }, + "until": { + "conditions": "Totdat voldaan is aan", + "label": "Totdat" + }, + "while": { + "conditions": "Zolang voldaan is aan voorwaarden", + "label": "Zolang" + } + } + }, "scene": { "label": "Activeer scène" }, @@ -1626,6 +1646,18 @@ "title": "MQTT", "topic": "onderwerp" }, + "ozw": { + "common": { + "node_id": "Knooppunt-ID", + "ozw_instance": "Instantie van OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Knoop gefaald", + "stage": "Stadium", + "zwave_info": "Z-Wave informatie" + } + }, "person": { "add_person": "Persoon toevoegen", "caption": "Personen", @@ -1994,6 +2026,8 @@ "group": "Groep", "header": "Z-Wave Knooppunt-beheer", "introduction": "Voer Z-Wave commando's uit die een enkel knooppunt beïnvloeden. Kies een knooppunt om een lijst met beschikbare commando's te zien.", + "max_associations": "Maximale associaties:", + "node_group_associations": "Knooppuntgroepassociaties", "node_protection": "Node beveiliging", "node_to_control": "Node om te besturen", "nodes": "Knooppunten", @@ -2392,6 +2426,9 @@ "para_migrate": "Home Assistant kan ID's voor al je kaarten en weergaven automatisch voor je toevoegen door op de knop 'Migrate config' te klikken.", "para_no_id": "Dit element heeft geen ID. Voeg een ID toe aan dit element in 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Kies een weergave om de kaart naartoe te verplaatsen" + }, "raw_editor": { "confirm_remove_config_text": "We zullen je Lovelace gebruikersinterface automatisch genereren met je gebieden en apparaten als je de huidige Lovelace gebruikersinterface verwijdert.", "confirm_remove_config_title": "Weet je zeker dat je de huidige Lovelace gebruikersinterface wilt verwijderen? We zullen automatisch een nieuwe Lovelace gebruikersinterface genereren op basis van je gebieden en apparaten.", @@ -2420,7 +2457,8 @@ "yaml_mode": "Je gebruikt de YAML-modus, wat betekent dat je jouw Lovelace-configuratie niet vanuit de gebruikersinterface kunt wijzigen. Als je Lovelace vanuit de gebruikersinterface wilt wijzigen, verwijder dan 'mode: yaml' uit de Lovelace-configuratie in 'configuration.yaml'." }, "select_view": { - "dashboard_label": "Dashboard" + "dashboard_label": "Dashboard", + "header": "Kies een weergave" }, "suggest_card": { "add": "Voeg toe aan de Lovelace gebruikersinterface", @@ -2739,7 +2777,9 @@ "header": "Verbinding automatisch verbreken" }, "themes": { + "accent_color": "Accentkleur", "dark_mode": { + "auto": "Automatisch", "dark": "Donker", "light": "Licht" }, @@ -2747,7 +2787,8 @@ "error_no_theme": "Geen thema's beschikbaar.", "header": "Thema", "link_promo": "Meer informatie over thema's", - "primary_color": "Primaire kleur" + "primary_color": "Primaire kleur", + "reset": "Herstel" }, "vibrate": { "description": "Schakel trillingen op dit apparaat in of uit wanneer u apparaten bestuurt.", diff --git a/translations/frontend/nn.json b/translations/frontend/nn.json index 69b3e297fb..75df383626 100644 --- a/translations/frontend/nn.json +++ b/translations/frontend/nn.json @@ -985,7 +985,7 @@ "no_device": "Oppføringar utan einingar", "no_devices": "Denne integrasjonen har ingen oppføringar", "options": "Val", - "rename": "Gi nytt namn", + "rename": "Endre namn", "restart_confirm": "Restart Home Assistant for å fjerne denne integrasjonen", "system_options": "Systemval", "unnamed_entry": "Oppføring utan namn" diff --git a/translations/frontend/sk.json b/translations/frontend/sk.json index d51981496a..e396769f18 100644 --- a/translations/frontend/sk.json +++ b/translations/frontend/sk.json @@ -48,6 +48,11 @@ "none": "Žiadny", "sleep": "Pohotovostný režim" } + }, + "humidifier": { + "mode": { + "auto": "Auto" + } } }, "state_badge": { @@ -206,6 +211,8 @@ "stopped": "Zastavené" }, "default": { + "off": "Vypnutý", + "on": "Zapnutý", "unavailable": "Nedostupný", "unknown": "Neznámy" }, @@ -385,6 +392,10 @@ "reverse": "Reverzný", "speed": "Rýchlosť" }, + "humidifier": { + "humidity": "Cieľová vlhkosť", + "mode": "Režim" + }, "light": { "brightness": "Jas", "color_temperature": "Teplota farby", @@ -408,6 +419,7 @@ "activate": "Aktivovať" }, "script": { + "cancel": "Zrušiť", "execute": "Vykonať" }, "service": { @@ -468,11 +480,15 @@ } }, "common": { + "and": "a", + "back": "Späť", "cancel": "Zrušiť", "close": "Zavrieť", "delete": "Odstrániť", "loading": "Načítava sa", + "next": "Ďalej", "no": "Nie", + "refresh": "Obnoviť", "save": "Uložiť", "successfully_deleted": "Úspešne odstránené", "successfully_saved": "Úspešne uložené", @@ -493,6 +509,13 @@ "clear": "Vyčistiť", "show_areas": "Zobraziť oblasti" }, + "data-table": { + "no-data": "Žiadne údaje" + }, + "date-range-picker": { + "end_date": "Dátum konca", + "start_date": "Dátum začiatku" + }, "device-picker": { "clear": "Vyčistiť", "device": "Zariadenie", @@ -609,6 +632,7 @@ }, "more_info_control": { "dismiss": "Zrušiť dialógové okno", + "edit": "Upraviť entitu", "person": { "create_zone": "Vytvoriť zónu z aktuálnej polohy" }, @@ -648,6 +672,7 @@ "deserialize": "Pokus interpretovať správy MQTT ako JSON", "entities": "Entity", "no_entities": "Žiadne entity", + "no_triggers": "Žiadne spúšťače", "recent_messages": "{n} naposledy prijaté správy", "show_as_yaml": "Zobraziť ako YAML", "title": "Informácie o ladení {device}", @@ -718,7 +743,14 @@ "triggered": "Spustené {name}" }, "panel": { + "calendar": { + "my_calendars": "Moje kalendáre", + "today": "Dnes" + }, "config": { + "advanced_mode": { + "link_profile_page": "vaša profilová stránka" + }, "areas": { "caption": "Register oblastí", "data_table": { @@ -734,6 +766,8 @@ "create": "VYTVORIŤ", "default_name": "Nová oblasť", "delete": "VYMAZAŤ", + "name": "Názov", + "name_required": "Názov je povinný", "update": "AKTUALIZOVAŤ" }, "picker": { @@ -760,6 +794,12 @@ "name": "Akcia", "type_select": "Typ akcie", "type": { + "choose": { + "add_option": "Pridať možnosť", + "conditions": "Podmienky", + "remove_option": "Odstrániť možnosť", + "sequence": "Akcie" + }, "condition": { "label": "Podmienka" }, @@ -768,6 +808,7 @@ "label": "Oneskorenie" }, "device_id": { + "action": "Akcia", "extra_fields": { "code": "Kód" }, @@ -778,6 +819,9 @@ "label": "Odpáliť udalosť", "service_data": "Dáta služby" }, + "repeat": { + "sequence": "Akcie" + }, "scene": { "label": "Aktivovať scénu" }, @@ -866,6 +910,16 @@ "introduction": "Použite automatizácie, aby váš domov ožil", "load_error_not_editable": "Len automatizácie v automations.yaml je možné upravovať.", "load_error_unknown": "Chyba pri načítaní automatizácie ({err_no}).", + "max": { + "queued": "Dĺžka fronty" + }, + "modes": { + "documentation": "dokumentácia automatizácie", + "label": "Režim", + "parallel": "Paralelne", + "queued": "Fronta", + "restart": "Reštart" + }, "save": "Uložiť", "triggers": { "add": "Pridať spúšťač", @@ -1135,7 +1189,9 @@ "edit_requires_storage": "Editor je zablokovaný, pretože konfigurácia je uložená v configuration.yaml", "elevation": "Nadmorská výška", "elevation_meters": "metrov", + "external_url": "Externá adresa URL", "imperial_example": "Fahrenheita, libry", + "internal_url": "Interná adresa URL", "latitude": "Zemepisná šírka", "location_name": "Názov vašej Home Assistant inštalácie", "longitude": "Zemepisná dĺžka", @@ -1194,12 +1250,14 @@ }, "delete": "Odstrániť", "description": "Spravovať pripojené zariadenia", + "device_info": "Informácie o zariadení", "entities": { "add_entities_lovelace": "Pridať do Lovelace", "entities": "Entity", "none": "Toto zariadenie nemá žiadne entity" }, "name": "Názov", + "no_devices": "Žiadne zariadenia", "scene": { "create": "Vytvorte scénu pomocou zariadenia", "no_scenes": "Žiadne scény", @@ -1244,6 +1302,7 @@ "introduction": "Home Assistant vedie register všetkých subjektov, ktoré kedy videl a ktoré môžu byť jednoznačne identifikované. Každá z týchto entít bude mať pridelené ID, ktoré bude vyhradené len pre tento subjekt.", "introduction2": "Použite register entít na prepísanie mena, zmenu ID entity alebo odstránenie položky z Home Assistant. Poznámka: Odstránenie položky databázy entít neodstráni entitu. Postupujte podľa nižšie uvedeného odkazu a odstráňte ho z integračnej stránky.", "remove_selected": { + "button": "Odstrániť vybraté", "confirm_partly_title": "Iba {number} vybrané entity môžu byť odstránené.", "confirm_text": "Entity je možné odstrániť, iba ak ich integrácia už neposkytuje.", "confirm_title": "Chcete odstrániť {number} entity?" @@ -1251,11 +1310,13 @@ "selected": "{number} vybrané", "status": { "ok": "Ok", - "readonly": "Len na čítanie" + "readonly": "Len na čítanie", + "unavailable": "Nedostupné" } } }, "filtering": { + "clear": "Vyčistiť", "filtering_by": "Filtrovanie podľa" }, "header": "Konfigurovať Home Assistant", @@ -1299,6 +1360,9 @@ "system_health_error": "Súčasť System Health nie je načítaná. Pridajte 'system_health:' do súboru configuration.yaml", "title": "Info" }, + "integration_panel_move": { + "link_integration_page": "stránka integrácie" + }, "integrations": { "add_integration": "Pridať integráciu", "caption": "Integrácie", @@ -1308,6 +1372,7 @@ "delete_button": "Odstrániť {integration}", "delete_confirm": "Naozaj chcete odstrániť túto integráciu?", "device_unavailable": "zariadenie nie je k dispozícii", + "documentation": "Dokumentácia", "entity_unavailable": "entita nie je k dispozícii", "firmware": "Firmvér: {version}", "hub": "Pripojené cez", @@ -1323,6 +1388,8 @@ "system_options_button": "Systémové možnosti pre {integration}" }, "config_flow": { + "aborted": "Prerušené", + "close": "Zavrieť", "created_config": "Vytvorená konfigurácia pre {name}.", "dismiss": "Zrušiť dialógové okno", "error_saving_area": "Chyba pri ukladaní oblasti: {error}", @@ -1331,7 +1398,9 @@ "open_site": "Otvoriť webovú stránku" }, "finish": "Dokončiť", - "loading_first_time": "Počkajte, kým sa nainštaluje integrácia" + "loading_first_time": "Počkajte, kým sa nainštaluje integrácia", + "not_all_required_fields": "Nie sú vyplnené všetky povinné polia.", + "submit": "Odoslať" }, "configure": "Konfigurovať", "configured": "Nakonfigurovaný", @@ -1449,6 +1518,7 @@ } }, "mqtt": { + "button": "Konfigurovať", "description_listen": "Počúvať tému", "description_publish": "Publikovať paket", "listening_to": "Počúvam", @@ -1507,6 +1577,7 @@ "introduction": "Entity, ktoré nepatria zariadeniu, môžete nastaviť tu.", "without_device": "Entity bez zariadenia" }, + "icon": "Ikona", "introduction": "Využite scény na oživenie vášho domova.", "load_error_not_editable": "Upraviť je možné iba scény zo scenes.yaml.", "load_error_unknown": "Chyba pri načítaní scény ({err_no}).", @@ -1520,6 +1591,9 @@ "delete_scene": "Odstrániť scénu", "edit_scene": "Upraviť scénu", "header": "Editor scén", + "headers": { + "name": "Názov" + }, "introduction": "Editor scén vám umožňuje vytvárať a upravovať scény. Postupujte podľa odkazu nižšie a prečítajte si pokyny, aby ste sa uistili, že ste Home Assistant nakonfigurovali správne.", "learn_more": "Získajte viac informácií o scénach", "no_scenes": "Nemohli sme nájsť žiadne editovateľné scény", @@ -1537,15 +1611,31 @@ "delete_confirm": "Naozaj chcete odstrániť tento skript?", "delete_script": "Odstrániť skript", "header": "Skript: {name}", + "icon": "Ikona", + "id": "Entity ID", + "id_already_exists": "Toto ID už existuje", "introduction": "Na vykonanie sledu akcií použite skripty.", "link_available_actions": "Získajte viac informácií o dostupných akciách.", "load_error_not_editable": "Iba skripty zo súboru scripts.yaml sú editovateľné.", + "max": { + "queued": "Dĺžka fronty" + }, + "modes": { + "documentation": "dokumentácia skriptu", + "label": "Režim", + "parallel": "Paralelne", + "queued": "Fronta", + "restart": "Reštart" + }, "sequence": "Sekvencia", "sequence_sentence": "Sled akcií tohto skriptu" }, "picker": { "add_script": "Pridať skript", "header": "Editor skriptov", + "headers": { + "name": "Názov" + }, "introduction": "Editor skriptov vám umožňuje vytvárať a upravovať skripty. Postupujte podľa odkazu nižšie a prečítajte si pokyny, aby ste sa uistili, že ste Home Assistant nakonfigurovali správne.", "learn_more": "Viac informácií o skriptoch", "no_scripts": "Nenašli sa žiadne editovateľné skripty", @@ -1605,11 +1695,20 @@ "delete_user": "Vymazať používateľa", "group": "Skupina", "id": "ID", + "name": "Názov", "owner": "Vlastník", "system_generated": "Systémom vytvorený", "system_generated_users_not_editable": "Nie je možné aktualizovať používateľov generovaných systémom.", "system_generated_users_not_removable": "Nie je možné odstrániť používateľov generovaných systémom.", - "unnamed_user": "Nepomenovaný používateľ" + "unnamed_user": "Nepomenovaný používateľ", + "update_user": "Aktualizovať" + }, + "picker": { + "headers": { + "group": "Skupina", + "name": "Názov", + "system": "Systém" + } } }, "zha": { @@ -1623,6 +1722,7 @@ "caption": "Pridať zariadenia", "description": "Pridať zariadenia do siete ZigBee" }, + "button": "Konfigurovať", "caption": "ZHA", "cluster_attributes": { "attributes_of_cluster": "Atribúty vybraného klastra", @@ -1693,6 +1793,9 @@ "header": "Správa siete", "introduction": "Príkazy, ktoré ovplyvňujú celú sieť" }, + "network": { + "caption": "Sieť" + }, "node_management": { "header": "Správa Zariadenia", "help_node_dropdown": "Vyberte zariadenie na zobrazenie možností zariadenia.", @@ -1732,6 +1835,7 @@ "no_zones_created_yet": "Zdá sa, že ste ešte nevytvorili žiadne zóny." }, "zwave": { + "button": "Konfigurovať", "caption": "Z-Wave", "common": { "index": "Index", @@ -1772,6 +1876,7 @@ "add_node_secure": "Bezpečne pridať zariadenie", "cancel_command": "Zrušiť príkaz", "heal_network": "Vyliečiť sieť", + "refresh_entity": "Obnoviť entitu", "remove_node": "Odstrániť zariadenie", "save_config": "Uložiť konfiguráciu", "soft_reset": "Softvérový reset", @@ -1843,11 +1948,23 @@ }, "history": { "period": "Obdobie", + "ranges": { + "last_week": "Minulý týždeň", + "this_week": "Tento týždeň", + "today": "Dnes", + "yesterday": "Včera" + }, "showing_entries": "Zobrazujú sa záznamy pre" }, "logbook": { "entries_not_found": "Nenašli sa žiadne záznamy v denníku.", "period": "Obdobie", + "ranges": { + "last_week": "Minulý týždeň", + "this_week": "Tento týždeň", + "today": "Dnes", + "yesterday": "Včera" + }, "showing_entries": "Zobrazujú sa záznamy za obdobie" }, "lovelace": { @@ -1883,6 +2000,10 @@ "add_item": "Pridať položku", "checked_items": "Označené položky", "clear_items": "Vymazať označené položky" + }, + "starting": { + "description": "Home Assistant sa spúšťa, čakajte prosím...", + "header": "Home Assistant sa spúšťa..." } }, "changed_toast": { @@ -1939,9 +2060,12 @@ "image": "Cesta k obrázku", "manual": "Ručne", "manual_description": "Potrebujete pridať vlastnú kartu, alebo chcete len ručne napísať yaml?", + "maximum": "Maximum", + "minimum": "Minimum", "name": "Názov", "no_theme": "Žiadna téma", "refresh_interval": "Interval obnovenia", + "search": "Hľadať", "show_icon": "Zobraziť ikonu?", "show_name": "Zobraziť názov?", "show_state": "Zobraziť stav?", @@ -1962,6 +2086,9 @@ "horizontal-stack": { "name": "Horizontálne zarovnanie" }, + "humidifier": { + "name": "Zvlhčovač" + }, "iframe": { "name": "iFrame" }, @@ -2027,7 +2154,8 @@ }, "weather-forecast": { "description": "Karta Predpoveď počasia zobrazuje počasie. Je veľmi užitočné ju zahrnúť do rozhrania, ktoré ľudia zobrazujú na stene.", - "name": "Predpoveď počasia" + "name": "Predpoveď počasia", + "show_forecast": "Zobraziť predpoveď" } }, "cardpicker": { @@ -2051,7 +2179,8 @@ "edit_lovelace": { "edit_title": "Upraviť názov", "explanation": "Tento názov sa zobrazuje nad všetkými vašimi zobrazeniami v Lovelace.", - "header": "Názov vášho Lovelace UI" + "header": "Názov vášho Lovelace UI", + "title": "Názov" }, "edit_view": { "add": "Pridať zobrazenie", @@ -2059,6 +2188,8 @@ "edit": "Upraviť zobrazenie", "header": "Konfigurácia zobrazenia", "header_name": "{name} Zobraziť konfiguráciu", + "move_left": "Presunúť zobrazenie doľava", + "move_right": "Presunúť zobrazenie doprava", "tab_badges": "Odznaky", "tab_settings": "Nastavenia", "tab_visibility": "Viditeľnosť", @@ -2077,6 +2208,9 @@ "para_migrate": "Home Assistant môže automaticky pridať identifikátory pre všetky vaše karty a zobrazenia, keď kliknete na tlačidlo 'Migrovať konfiguráciu'.", "para_no_id": "Tento prvok nemá žiadne ID. Doplňte, prosím, ID pre tento prvok v súbore 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Vyberte zobrazenie, do ktorého chcete kartu presunúť" + }, "raw_editor": { "confirm_remove_config_text": "Ak odstránite svoju konfiguráciu používateľského rozhrania Lovelace, automaticky vygenerujeme vaše zobrazenia používateľského rozhrania Lovelace s vašimi oblasťami a zariadeniami.", "confirm_remove_config_title": "Naozaj chcete odstrániť konfiguráciu používateľského rozhrania Lovelace? Vaše zobrazenia používateľské rozhranie Lovelace automaticky vygenerujeme s vašimi oblasťami a zariadeniami.", @@ -2102,6 +2236,10 @@ "yaml_control": "Ak chcete prevziať kontrolu v režime YAML, vytvorte súbor YAML s názvom, ktorý ste uviedli vo svojej konfigurácii pre tento dashboard alebo predvolený súbor 'ui-lovelace.yaml'.", "yaml_mode": "Používate režim YAML, čo znamená, že nemôžete zmeniť konfiguráciu Lovelace z používateľského rozhrania. Ak chcete zmeniť Lovelace z UI, odstráňte 'mode: yaml' z vašej konfigurácie Lovelace v 'configuration.yaml.'" }, + "select_view": { + "dashboard_label": "Dashboard", + "header": "Vyberte zobrazenie" + }, "suggest_card": { "add": "Pridať do používateľského rozhrania Lovelace", "create_own": "Vyberte inú kartu", @@ -2116,6 +2254,7 @@ } }, "menu": { + "close": "Zavrieť", "configure_ui": "Konfigurovať používateľské rozhranie", "exit_edit_mode": "Skončiť režim úprav používateľského rozhrania", "help": "Pomoc", @@ -2146,7 +2285,8 @@ "attribute_not_found": "Atribút {attribute} nie je k dispozícii v: {entity}", "entity_non_numeric": "Entita je nečíselná: {entity}", "entity_not_found": "Entita nie je k dispozícií {entity}", - "entity_unavailable": "Entita momentálne nie je k dispozícií {entity}" + "entity_unavailable": "Entita momentálne nie je k dispozícií {entity}", + "starting": "Home Assistant sa spúšťa, zatiaľ nemusí byť všetko k dispozícii" } }, "mailbox": { @@ -2159,6 +2299,7 @@ "abort_intro": "Prihlásenie bolo zrušené", "authorizing_client": "Chystáte sa poskytnúť {clientId} prístup k vašej inštancii Home Assistantu.", "form": { + "next": "Ďalej", "providers": { "command_line": { "abort": { @@ -2341,6 +2482,11 @@ "submit": "Odoslať" }, "current_user": "Momentálne ste prihlásení ako {fullName}.", + "dashboard": { + "description": "Vyberte predvolený dashboard pre toto zariadenie.", + "dropdown_label": "Dashboard", + "header": "Dashboard" + }, "force_narrow": { "description": "Predvolene sa skryje bočný panel, podobne ako v prípade mobilných zariadení.", "header": "Vždy skryť bočný panel" @@ -2402,10 +2548,18 @@ "token_title": "Obnovovací token pre {clientId}" }, "themes": { + "accent_color": "Farba zvýraznenia", + "dark_mode": { + "auto": "Automaticky", + "dark": "Tmavá", + "light": "Svetlá" + }, "dropdown_label": "Téma", "error_no_theme": "Nie sú k dispozícii žiadne témy.", "header": "Téma", - "link_promo": "Získajte viac informácií o témach" + "link_promo": "Získajte viac informácií o témach", + "primary_color": "Primárna farba", + "reset": "Reset" }, "vibrate": { "description": "Pri ovládaní zariadení povoľte alebo zakážte vibrácie tohto zariadenia.", diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index 6101afd109..d7ccb3da20 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -2475,7 +2475,7 @@ }, "menu": { "close": "关闭", - "configure_ui": "配置 UI", + "configure_ui": "编辑仪表盘", "exit_edit_mode": "退出 UI 编辑模式", "help": "帮助", "refresh": "刷新", From 4163b35b32b977762d9fd38d3b2f9a8bc53e5c10 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Sat, 15 Aug 2020 00:32:27 +0000 Subject: [PATCH 22/38] [ci skip] Translation update --- translations/frontend/de.json | 10 ++++-- translations/frontend/he.json | 58 +++++++++++++++++++++++++++++++++-- translations/frontend/sk.json | 26 +++++++++------- 3 files changed, 79 insertions(+), 15 deletions(-) diff --git a/translations/frontend/de.json b/translations/frontend/de.json index ae49612394..130ade04c7 100644 --- a/translations/frontend/de.json +++ b/translations/frontend/de.json @@ -1621,7 +1621,7 @@ }, "ozw": { "device_info": { - "zwave_info": "Z-wave Infos" + "zwave_info": "Z-Wave Infos" } }, "person": { @@ -2736,10 +2736,16 @@ "header": "Verbindung automatisch schließen" }, "themes": { + "accent_color": "Akzentfarbe", + "dark_mode": { + "dark": "Dunkel", + "light": "Hell" + }, "dropdown_label": "Thema", "error_no_theme": "Keine Themen verfügbar.", "header": "Thema", - "link_promo": "Erfahre mehr über Themen" + "link_promo": "Erfahre mehr über Themen", + "primary_color": "Primärfarbe" }, "vibrate": { "description": "Aktiviere oder deaktiviere die Vibration an diesem Gerät, wenn du Geräte steuerst.", diff --git a/translations/frontend/he.json b/translations/frontend/he.json index b004705a41..e6ae133790 100644 --- a/translations/frontend/he.json +++ b/translations/frontend/he.json @@ -359,7 +359,7 @@ }, "automation": { "last_triggered": "הפעלה אחרונה", - "trigger": "מפעיל" + "trigger": "הרץ" }, "camera": { "not_available": "התמונה אינה זמינה" @@ -833,6 +833,15 @@ "name": "פעולה", "type_select": "סוג פעולה", "type": { + "choose": { + "add_option": "הוסף אפשרות", + "conditions": "תנאים", + "default": "פעולות ברירת מחדל", + "label": "בחר", + "option": "אפשרות {number}", + "remove_option": "הסר אפשרות", + "sequence": "פעולות" + }, "condition": { "label": "תנאי" }, @@ -852,6 +861,24 @@ "label": "ירה אירוע", "service_data": "נתוני שירות" }, + "repeat": { + "label": "חזור", + "sequence": "פעולות", + "type_select": "סוג חזרה", + "type": { + "count": { + "label": "ספירה" + }, + "until": { + "conditions": ")תנאי עד ש (Until", + "label": "עד ש" + }, + "while": { + "conditions": ")תנאי כל עוד (While", + "label": "כל עוד" + } + } + }, "scene": { "label": "הפעל סצנה" }, @@ -1619,6 +1646,18 @@ "title": "MQTT", "topic": "נושא" }, + "ozw": { + "common": { + "node_id": "מזהה רכיב", + "ozw_instance": "מופע OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "הרכיב נכשל", + "stage": "שלב", + "zwave_info": "מידע Z-Wave" + } + }, "person": { "add_person": "הוסף אדם", "caption": "אנשים", @@ -2387,6 +2426,9 @@ "para_migrate": "Home Assistant יכול להוסיף מזהה יחודי לכל הכרטיסיות והתצוגות שלך בצורה אוטומטית בכך שתלחץ על לחצן ״הגר הגדרה״.", "para_no_id": "האלמנט הנוכחי לא מכיל מזהה יחודיי. בבקשה הוסף מזהה יחודי לאלמט זה בקובץ 'ui-lovelace.yaml'." }, + "move_card": { + "header": "בחר תצוגה שאליה להעביר את הכרטיס" + }, "raw_editor": { "confirm_remove_config_text": "אנו ניצור אוטומטית את תצוגות ממשק המשתמש של Lovelace עם האזורים והמכשירים שלך אם תסיר את קונפיגורציית ממשק המשתמש שלך ב- Lovelace.", "confirm_remove_config_title": "האם אתה בטוח שברצונך להסיר את תצורת ממשק המשתמש של Lovelace? אנו נייצר אוטומטית את תצוגות ממשק המשתמש שלך ב- Lovelace עם האזורים והמכשירים שלך.", @@ -2414,6 +2456,10 @@ "yaml_control": "כדי לקבל שליטה במצב YAML, צור קובץ YAML עם השם שציינת ב-config עבור לוח מחוונים זה, או ברירת המחדל 'ui-lovelace.yaml'.", "yaml_mode": "אתה משתמש במצב YAML עבור לוח מחוונים זה ולכן אין באפשרותך לשנות את קונפיגורצית Lovelace מממשק המשתמש. אם ברצונך לנהל לוח מחוונים זה מממשק המשתמש, הסר 'mode: yaml' מתצורת Loverlace ב 'configuration.yaml.'." }, + "select_view": { + "dashboard_label": "לוח בקרה", + "header": "בחר תצוגה" + }, "suggest_card": { "add": "הוסף לממשק המשתמש של Lovelace", "create_own": "בחר כרטיס אחר", @@ -2731,10 +2777,18 @@ "header": "סגור חיבור באופן אוטומטי" }, "themes": { + "accent_color": "צבע הדגשה", + "dark_mode": { + "auto": "אוטומטי", + "dark": "כהה", + "light": "בהיר" + }, "dropdown_label": "ערכת נושא", "error_no_theme": "אין ערכות נושא זמינות.", "header": "ערכת נושא", - "link_promo": "למד אודות ערכות נושא" + "link_promo": "למד אודות ערכות נושא", + "primary_color": "בצע ראשי", + "reset": "איפוס" }, "vibrate": { "description": "הפעל או בטל את הרטט במכשיר זה בעת שליטה בהתקנים.", diff --git a/translations/frontend/sk.json b/translations/frontend/sk.json index e396769f18..6e865645c7 100644 --- a/translations/frontend/sk.json +++ b/translations/frontend/sk.json @@ -278,7 +278,7 @@ }, "sensor": { "off": "Neaktívny", - "on": "Aktívny" + "on": "Zapnutý" }, "sun": { "above_horizon": "Nad horizontom", @@ -628,7 +628,9 @@ "pattern": "Vzor regexu na overenie na strane klienta", "text": "Text" }, - "required_error_msg": "Toto pole je povinné" + "platform_not_loaded": "Integrácia {platform} sa nenačítala. Pridajte ju do svojej konfigurácie buď pridaním 'default_config:' alebo ''{platform}:''.", + "required_error_msg": "Toto pole je povinné", + "yaml_not_editable": "Nastavenia tejto entity nie je možné upravovať z UI. Iba entity nastavené z UI sú konfigurovateľné z UI." }, "more_info_control": { "dismiss": "Zrušiť dialógové okno", @@ -714,7 +716,7 @@ "unknown": "Neznámy", "zha_device_card": { "area_picker_label": "Oblasť", - "device_name_placeholder": "Používateľom zadaný názov", + "device_name_placeholder": "Zmeniť názov zariadenia", "update_name_button": "Aktualizovať názov" } } @@ -761,7 +763,7 @@ "confirmation_text": "Všetky zariadenia v tejto oblasti ostanú nepriradené.", "confirmation_title": "Naozaj chcete odstrániť túto oblasť?" }, - "description": "Prehľad všetkých oblastí vo vašej domácnosti.", + "description": "Spravujte všetky oblasti vo vašej domácnosti.", "editor": { "create": "VYTVORIŤ", "default_name": "Nová oblasť", @@ -1274,7 +1276,7 @@ }, "entities": { "caption": "Register entít", - "description": "Prehľad všetkých známych entít.", + "description": "Spravujte všetky známe entity.", "picker": { "disable_selected": { "button": "Zrušiť vybraté", @@ -1348,6 +1350,7 @@ "info": { "built_using": "Postavené pomocou", "custom_uis": "Vlastné používateľské rozhrania:", + "description": "Zobraziť informácie o inštalácii Home Assistant", "developed_by": "Vyvinuté partiou úžasných ľudí.", "frontend": "frontend-ui", "frontend_version": "Verzia frontendu: {version} - {type}", @@ -1482,7 +1485,7 @@ "open": "Otvoriť" } }, - "description": "Nakonfigurujte si svoje Lovelace dashboardy", + "description": "Spravujte svoje Lovelace Dashboardy", "resources": { "cant_edit_yaml": "Používate Lovelace v režime YAML, preto nemôžete spravovať svoje prostriedky cez používateľské rozhranie. Spravujte ich v configuration.yaml.", "caption": "Prostriedky", @@ -1560,7 +1563,7 @@ "scene": { "activated": "Aktivovaná scéna {name}.", "caption": "Scény", - "description": "Vytvárajte a upravujte scény", + "description": "Správa scén", "editor": { "default_name": "Nová scéna", "devices": { @@ -1666,7 +1669,7 @@ "stop": "Zastaviť" }, "validation": { - "check_config": "Skontrolujte konfiguráciu", + "check_config": "Skontrolovať konfiguráciu", "heading": "Kontrola konfigurácie", "introduction": "Overte svoju konfiguráciu, ak ste nedávno vykonali nejaké zmeny v konfigurácii a chcete sa uistiť, že je to všetko v poriadku", "invalid": "Konfigurácia je neplatná", @@ -1715,6 +1718,7 @@ "add_device_page": { "discovery_text": "Tu sa zobrazia objavené zariadenia. Postupujte podľa pokynov pre zariadenie (zariadenia) a umiestnite zariadenie (zariadenia) do režimu párovania.", "header": "Zigbee Home Automation - Pridať zariadenia", + "no_devices_found": "Neboli nájdené žiadne zariadenia, uistite sa, že sú v režime párovania a udržujte ich pri prebudené počas zisťovania.", "search_again": "Hľadať znova", "spinner": "Vyhľadávanie ZHA Zigbee zariadení ..." }, @@ -1769,7 +1773,7 @@ "create_group": "Zigbee Home Automation - Vytvoriť skupinu", "create_group_details": "Zadajte požadované údaje na vytvorenie novej skupiny ZigBee", "creating_group": "Vytvorenie skupiny", - "description": "Vytvorenie a úprava skupín ZigBee", + "description": "Správa skupín Zigbee", "group_details": "Tu sú všetky podrobnosti o vybranej skupine Zigbee.", "group_id": "ID skupiny", "group_info": "Informácie o skupine", @@ -2234,7 +2238,7 @@ "save": "Prevziať kontrolu", "yaml_config": "Na začiatok vám pomôžeme so súčasnou konfiguráciou tohto dashboardu:", "yaml_control": "Ak chcete prevziať kontrolu v režime YAML, vytvorte súbor YAML s názvom, ktorý ste uviedli vo svojej konfigurácii pre tento dashboard alebo predvolený súbor 'ui-lovelace.yaml'.", - "yaml_mode": "Používate režim YAML, čo znamená, že nemôžete zmeniť konfiguráciu Lovelace z používateľského rozhrania. Ak chcete zmeniť Lovelace z UI, odstráňte 'mode: yaml' z vašej konfigurácie Lovelace v 'configuration.yaml.'" + "yaml_mode": "Používate režim YAML, čo znamená, že nemôžete zmeniť konfiguráciu Lovelace z UI. Ak chcete zmeniť Lovelace z UI, odstráňte 'mode: yaml' z vašej konfigurácie Lovelace v 'configuration.yaml.'" }, "select_view": { "dashboard_label": "Dashboard", @@ -2255,7 +2259,7 @@ }, "menu": { "close": "Zavrieť", - "configure_ui": "Konfigurovať používateľské rozhranie", + "configure_ui": "Upraviť Dashboard", "exit_edit_mode": "Skončiť režim úprav používateľského rozhrania", "help": "Pomoc", "refresh": "Obnoviť", From 2a58726caf026571e969c2410c39291904028ff3 Mon Sep 17 00:00:00 2001 From: gibwar Date: Sun, 16 Aug 2020 16:51:50 -0600 Subject: [PATCH 23/38] Fix exceptional weither icon size (#6425) (#6634) The weather icon for the `exceptional` state uses a different DOM layout than the other icons, using a `.weather-icon` class that sets the size to 64px (52px on narrow). This updates the `forecast-icon > *` class to set the correct variable to match the expected `40px` and works on all sizes from `veryverynarrow` to normal. --- src/panels/lovelace/cards/hui-weather-forecast-card.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/panels/lovelace/cards/hui-weather-forecast-card.ts b/src/panels/lovelace/cards/hui-weather-forecast-card.ts index 0af5d4b979..234549a4fd 100644 --- a/src/panels/lovelace/cards/hui-weather-forecast-card.ts +++ b/src/panels/lovelace/cards/hui-weather-forecast-card.ts @@ -436,6 +436,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { .forecast-image-icon > * { width: 40px; height: 40px; + --mdc-icon-size: 40px; } .forecast-icon { @@ -469,7 +470,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard { width: 52px; } - :host([narrow]) .weather-icon { + :host([narrow]) .icon-image .weather-icon { --mdc-icon-size: 52px; } From aab86e00ec77ec4b9a300107a0b6dd490297d251 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Mon, 17 Aug 2020 00:32:14 +0000 Subject: [PATCH 24/38] [ci skip] Translation update --- translations/frontend/ar.json | 5 +++ translations/frontend/nn.json | 75 ++++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/translations/frontend/ar.json b/translations/frontend/ar.json index 5063aae8c7..3504230a0d 100644 --- a/translations/frontend/ar.json +++ b/translations/frontend/ar.json @@ -465,6 +465,7 @@ }, "relative_time": { "duration": { + "hour": "{count} {count, plural,\none {ساعة}\nother {ساعات}\n}", "minute": "{count} {count, plural,\n one {دقيقة}\n other {دقائق}\n}" }, "future": "قبل {time}", @@ -546,6 +547,7 @@ "zha_device_info": { "buttons": { "add": "أضف أجهزة عبر هذا الجهاز", + "clusters": "إدارة العناقيد", "zigbee_information": "معلومات Zigbee" }, "device_signature": "توقيع جهاز Zigbee", @@ -1153,6 +1155,9 @@ "discovered_text": "ستظهر الأجهزة هنا عند إكتشافها." }, "button": "كوِن", + "clusters": { + "header": "عناقيد" + }, "groups": { "zha_zigbee_groups": "مجموعات ZHA Zigbee" }, diff --git a/translations/frontend/nn.json b/translations/frontend/nn.json index 75df383626..c865e0c752 100644 --- a/translations/frontend/nn.json +++ b/translations/frontend/nn.json @@ -397,6 +397,8 @@ "activate": "Aktiver" }, "script": { + "cancel": "Avbryt", + "cancel_multiple": "Avbryt {number}", "execute": "Utfør" }, "service": { @@ -463,7 +465,9 @@ "back": "Tilbake", "cancel": "Avbryt", "delete": "Slett", + "error_required": "Påkrevd", "loading": "Lastar", + "menu": "Meny", "next": "Neste", "previous": "Førre", "refresh": "Oppdater ", @@ -485,6 +489,9 @@ "clear": "Klar ", "show_areas": "Vis områda" }, + "data-table": { + "no-data": "Ingen data" + }, "device-picker": { "device": "Enhet", "no_area": "Inga område", @@ -600,11 +607,12 @@ "services": { "reconfigure": "Konfigurer ZHA-eininga (heal device) på nytt. Bruk dette om du har problem med eininga. Dersom eininga går på batteri, ver sikker på at den er vaken og tek i mot kommandar når du brukar denne tenesta.", "remove": "Fjern eining frå Zigbee-nettverket", - "updateDeviceName": "Gje oppføringa eit eige namn i oppføringsregisteret. " + "updateDeviceName": "Gje eininga eit tilpassa namn i einingsregisteret. " }, + "unknown": "Ukjent", "zha_device_card": { "area_picker_label": "Område", - "device_name_placeholder": "Gitt brukarnamn", + "device_name_placeholder": "Endre navn på eining", "update_name_button": "Oppdater namn" } } @@ -692,6 +700,9 @@ "label": "Køyr hending", "service_data": "Tenestedata" }, + "repeat": { + "label": "Gjenta" + }, "service": { "label": "Hent teneste", "service_data": "Tenestedata" @@ -718,6 +729,10 @@ "type": { "device": { "condition": "Føresetnad ", + "extra_fields": { + "above": "Over", + "below": "Under" + }, "label": "Eining" }, "not": { @@ -764,6 +779,11 @@ "introduction": "Bruk automasjonar til å gi liv til heimen din", "load_error_not_editable": "Berre automasjonar i automations.yaml kan redigerast.", "load_error_unknown": "Feil ved lasting av automasjon ({err_no}).", + "modes": { + "restart": "Omstart" + }, + "move_down": "Flytt ned", + "move_up": "Flytt opp", "save": "Lagre", "triggers": { "add": "Legg til utløysar", @@ -777,6 +797,10 @@ "type_select": "Utløysartype", "type": { "device": { + "extra_fields": { + "above": "Over", + "below": "Under" + }, "label": "Oppføring", "trigger": "Utløysar " }, @@ -873,7 +897,19 @@ "caption": "Home Assistant Cloud", "description_features": "Kontroller når du ikkje er heime og integrer med Alexa og Google Assistant", "description_login": "Logga inn som {email}", - "description_not_login": "Ikkje logga inn" + "description_not_login": "Ikkje logga inn", + "forgot_password": { + "email": "E-post", + "subtitle": "Gløymt passordet ditt", + "title": "Gløymt passord" + }, + "login": { + "email": "E-post", + "forgot_password": "gløymt passordet?", + "password": "Passord", + "password_error_msg": "Passord er minst 8 teikn", + "sign_in": "Logg inn" + } }, "core": { "caption": "Generelt", @@ -963,6 +999,7 @@ }, "header": "Konfigurer Home Assistant", "info": { + "caption": "Info", "documentation": "Dokumentasjon ", "integrations": "Integrasjonar", "issues": "Problem ", @@ -1015,6 +1052,7 @@ }, "introduction": "Her er det mogleg å konfigurere dine komponenter og Home Assistant. Ikkje alt er mogleg å konfigurere frå brukarsnittet endå, men vi jobbar med saka.", "logs": { + "caption": "Loggar", "title": "Loggar" }, "mqtt": { @@ -1031,6 +1069,9 @@ } }, "scene": { + "editor": { + "icon": "Ikon" + }, "picker": { "headers": { "name": "Namn" @@ -1040,6 +1081,14 @@ "script": { "caption": "Skript", "description": "Lag og rediger skript", + "editor": { + "icon": "Ikon", + "id_already_exists": "Denne ID-en finnast allereie", + "modes": { + "label": "Modus", + "restart": "Omstart" + } + }, "picker": { "headers": { "name": "Namn" @@ -1307,6 +1356,10 @@ "state_equal": "Tilstanden er lik", "state_not_equal": "Tilstanden er ikkje lik" }, + "config": { + "optional": "Valfri", + "required": "Påkrevd" + }, "entities": { "description": "Oppføringskortet er den vanlegaste korttypen. Den kan gruppere ting inn i lister." }, @@ -1317,13 +1370,20 @@ "name": "Oppføring " }, "gauge": { - "description": "Målarkortet er eit enkelt kort som let deg visuelt sjå sensordata." + "description": "Målarkortet er eit enkelt kort som let deg visuelt sjå sensordata.", + "severity": { + "green": "Grøn", + "red": "Rød" + } }, "generic": { "attribute": "Attributt", "double_tap_action": "Dobbeltrykk-handling", + "icon": "Ikon", "manual": "Manuelt", "manual_description": "Vil du legge til eit tilpassa kort eller vil du berre skrive yaml manuelt?", + "maximum": "Maksimum", + "minimum": "Minimum", "name": "Namn", "secondary_info_attribute": "Sekundærinfo-attributt", "state": "Tilstand" @@ -1361,12 +1421,14 @@ }, "edit_card": { "add": "Legg til kort", + "confirm_cancel": "Er du sikker på at du vil avbryte?", "delete": "Slett", "edit": "Redigere", "header": "Kortkonfigurasjon", "move": "Rørsle", "pick_card": "Vel kortet du vil legge til.", - "toggle_editor": "Bytt redigeringsverktøy" + "toggle_editor": "Bytt redigeringsverktøy", + "unsaved_changes": "Du har endringar som ikkje er lagra" }, "edit_lovelace": { "explanation": "Denne tittelen vert vist over alle visningane dine i Lovelace", @@ -1687,6 +1749,9 @@ "error_no_theme": "Ingen tema tilgjengeleg", "header": "Tema", "link_promo": "Lær om temaer" + }, + "vibrate": { + "header": "Vibrer" } }, "shopping-list": { From bce85395722037828ba5df6b8c7b4063b9868b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 17 Aug 2020 12:00:06 +0200 Subject: [PATCH 25/38] Add style to combobox (#6630) --- src/resources/styles.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/resources/styles.ts b/src/resources/styles.ts index c270d0a2f3..316ccf77e1 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -60,6 +60,7 @@ export const derivedStyles = { "material-body-text-color": "var(--primary-text-color)", "material-background-color": "var(--card-background-color)", "material-secondary-background-color": "var(--secondary-background-color)", + "material-secondary-text-color": "var(--secondary-text-color)", "mdc-checkbox-unchecked-color": "rgba(var(--rgb-primary-text-color), 0.54)", "mdc-checkbox-disabled-color": "var(--disabled-text-color)", "mdc-radio-unchecked-color": "rgba(var(--rgb-primary-text-color), 0.54)", From 6c918e346b044f1911b5cfe43698466c02b7a4ae Mon Sep 17 00:00:00 2001 From: "David F. Mulcahey" Date: Mon, 17 Aug 2020 08:17:18 -0400 Subject: [PATCH 26/38] Fix navigation after ZHA device removal (#6638) --- .../integration-elements/zha/ha-device-actions-zha.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts index d5d98dc68d..d6629b58c5 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts @@ -119,9 +119,11 @@ export class HaDeviceActionsZha extends LitElement { return; } - this.hass.callService("zha", "remove", { + await this.hass.callService("zha", "remove", { ieee_address: this._zhaDevice!.ieee, }); + + history.back(); } static get styles(): CSSResult[] { From 613470b44d1cc6d0e6997eb4f6a22902370c7f00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 17 Aug 2020 15:16:28 +0200 Subject: [PATCH 27/38] Set SameSite=Strict attribute for ingress_session (#6556) --- src/data/hassio/supervisor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/hassio/supervisor.ts b/src/data/hassio/supervisor.ts index 51454ad610..f6a7d2811c 100644 --- a/src/data/hassio/supervisor.ts +++ b/src/data/hassio/supervisor.ts @@ -71,7 +71,7 @@ export const createHassioSession = async (hass: HomeAssistant) => { "POST", "hassio/ingress/session" ); - document.cookie = `ingress_session=${response.data.session};path=/api/hassio_ingress/`; + document.cookie = `ingress_session=${response.data.session};path=/api/hassio_ingress/;SameSite=Strict`; }; export const setSupervisorOption = async ( From 21644ec8899c82add87d6d6fac981f7f720d6a80 Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Mon, 17 Aug 2020 09:07:29 -0500 Subject: [PATCH 28/38] Light More Info: Convert to Lit Element (#6592) * Update more info * Remove is unavailable * Remove divs * updates * Update src/dialogs/more-info/controls/more-info-light.ts * Update src/dialogs/more-info/controls/more-info-light.ts Co-authored-by: Bram Kragten Co-authored-by: Bram Kragten --- .../more-info/controls/more-info-light.js | 361 ------------------ .../more-info/controls/more-info-light.ts | 307 +++++++++++++++ src/types.ts | 4 + 3 files changed, 311 insertions(+), 361 deletions(-) delete mode 100644 src/dialogs/more-info/controls/more-info-light.js create mode 100644 src/dialogs/more-info/controls/more-info-light.ts diff --git a/src/dialogs/more-info/controls/more-info-light.js b/src/dialogs/more-info/controls/more-info-light.js deleted file mode 100644 index 0362e44822..0000000000 --- a/src/dialogs/more-info/controls/more-info-light.js +++ /dev/null @@ -1,361 +0,0 @@ -import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-listbox/paper-listbox"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { featureClassNames } from "../../../common/entity/feature_class_names"; -import "../../../components/ha-attributes"; -import "../../../components/ha-color-picker"; -import "../../../components/ha-labeled-slider"; -import "../../../components/ha-paper-dropdown-menu"; -import { EventsMixin } from "../../../mixins/events-mixin"; -import LocalizeMixin from "../../../mixins/localize-mixin"; -import "../../../components/ha-icon-button"; - -const FEATURE_CLASS_NAMES = { - 1: "has-brightness", - 2: "has-color_temp", - 4: "has-effect_list", - 16: "has-color", - 128: "has-white_value", -}; -/* - * @appliesMixin EventsMixin - */ -class MoreInfoLight extends LocalizeMixin(EventsMixin(PolymerElement)) { - static get template() { - return html` - - - -
-
- -
- -
- -
- -
- -
-
- - - -
- -
- - - - - -
- - -
- `; - } - - static get properties() { - return { - hass: { - type: Object, - }, - - stateObj: { - type: Object, - observer: "stateObjChanged", - }, - - brightnessSliderValue: { - type: Number, - value: 0, - }, - - ctSliderValue: { - type: Number, - value: 0, - }, - - wvSliderValue: { - type: Number, - value: 0, - }, - - hueSegments: { - type: Number, - value: 24, - }, - - saturationSegments: { - type: Number, - value: 8, - }, - - colorPickerColor: { - type: Object, - }, - }; - } - - stateObjChanged(newVal, oldVal) { - const props = { - brightnessSliderValue: 0, - }; - - if (newVal && newVal.state === "on") { - props.brightnessSliderValue = newVal.attributes.brightness; - props.ctSliderValue = newVal.attributes.color_temp; - props.wvSliderValue = newVal.attributes.white_value; - if (newVal.attributes.hs_color) { - props.colorPickerColor = { - h: newVal.attributes.hs_color[0], - s: newVal.attributes.hs_color[1] / 100, - }; - } - } - - this.setProperties(props); - - if (oldVal) { - setTimeout(() => { - this.fire("iron-resize"); - }, 500); - } - } - - computeClassNames(stateObj) { - const classes = [ - "content", - featureClassNames(stateObj, FEATURE_CLASS_NAMES), - ]; - if (stateObj && stateObj.state === "on") { - classes.push("is-on"); - } - if (stateObj && stateObj.state === "unavailable") { - classes.push("is-unavailable"); - } - return classes.join(" "); - } - - effectChanged(ev) { - const oldVal = this.stateObj.attributes.effect; - const newVal = ev.detail.value; - - if (!newVal || oldVal === newVal) return; - - this.hass.callService("light", "turn_on", { - entity_id: this.stateObj.entity_id, - effect: newVal, - }); - } - - brightnessSliderChanged(ev) { - const bri = parseInt(ev.target.value, 10); - - if (isNaN(bri)) return; - - this.hass.callService("light", "turn_on", { - entity_id: this.stateObj.entity_id, - brightness: bri, - }); - } - - ctSliderChanged(ev) { - const ct = parseInt(ev.target.value, 10); - - if (isNaN(ct)) return; - - this.hass.callService("light", "turn_on", { - entity_id: this.stateObj.entity_id, - color_temp: ct, - }); - } - - wvSliderChanged(ev) { - const wv = parseInt(ev.target.value, 10); - - if (isNaN(wv)) return; - - this.hass.callService("light", "turn_on", { - entity_id: this.stateObj.entity_id, - white_value: wv, - }); - } - - segmentClick() { - if (this.hueSegments === 24 && this.saturationSegments === 8) { - this.setProperties({ hueSegments: 0, saturationSegments: 0 }); - } else { - this.setProperties({ hueSegments: 24, saturationSegments: 8 }); - } - } - - serviceChangeColor(hass, entityId, color) { - hass.callService("light", "turn_on", { - entity_id: entityId, - hs_color: [color.h, color.s * 100], - }); - } - - /** - * Called when a new color has been picked. - * should be throttled with the 'throttle=' attribute of the color picker - */ - colorPicked(ev) { - this.serviceChangeColor(this.hass, this.stateObj.entity_id, ev.detail.hs); - } -} - -customElements.define("more-info-light", MoreInfoLight); diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts new file mode 100644 index 0000000000..3abab21a99 --- /dev/null +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -0,0 +1,307 @@ +import "@polymer/paper-item/paper-item"; +import "@polymer/paper-listbox/paper-listbox"; +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, + internalProperty, + PropertyValues, +} from "lit-element"; +import { classMap } from "lit-html/directives/class-map"; + +import { + SUPPORT_BRIGHTNESS, + SUPPORT_COLOR_TEMP, + SUPPORT_WHITE_VALUE, + SUPPORT_COLOR, + SUPPORT_EFFECT, +} from "../../../data/light"; +import { supportsFeature } from "../../../common/entity/supports-feature"; +import type { HomeAssistant, LightEntity } from "../../../types"; + +import "../../../components/ha-attributes"; +import "../../../components/ha-color-picker"; +import "../../../components/ha-labeled-slider"; +import "../../../components/ha-icon-button"; +import "../../../components/ha-paper-dropdown-menu"; + +interface HueSatColor { + h: number; + s: number; +} + +@customElement("more-info-light") +class MoreInfoLight extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj?: LightEntity; + + @internalProperty() private _brightnessSliderValue = 0; + + @internalProperty() private _ctSliderValue = 0; + + @internalProperty() private _wvSliderValue = 0; + + @internalProperty() private _hueSegments = 24; + + @internalProperty() private _saturationSegments = 8; + + @internalProperty() private _colorPickerColor?: HueSatColor; + + protected render(): TemplateResult { + if (!this.hass || !this.stateObj) { + return html``; + } + + return html` +
+ ${this.stateObj.state === "on" + ? html` + ${supportsFeature(this.stateObj!, SUPPORT_BRIGHTNESS) + ? html` + + ` + : ""} + ${supportsFeature(this.stateObj, SUPPORT_COLOR_TEMP) + ? html` + + ` + : ""} + ${supportsFeature(this.stateObj, SUPPORT_WHITE_VALUE) + ? html` + + ` + : ""} + ${supportsFeature(this.stateObj, SUPPORT_COLOR) + ? html` +
+ + + +
+ ` + : ""} + ${supportsFeature(this.stateObj, SUPPORT_EFFECT) && + this.stateObj!.attributes.effect_list?.length + ? html` + + ${this.stateObj.attributes.effect_list.map( + (effect: string) => html` + ${effect} + ` + )} + + + ` + : ""} + ` + : ""} + +
+ `; + } + + protected updated(changedProps: PropertyValues): void { + const stateObj = this.stateObj! as LightEntity; + if (changedProps.has("stateObj") && stateObj.state === "on") { + this._brightnessSliderValue = stateObj.attributes.brightness; + this._ctSliderValue = stateObj.attributes.color_temp; + this._wvSliderValue = stateObj.attributes.white_value; + + if (stateObj.attributes.hs_color) { + this._colorPickerColor = { + h: stateObj.attributes.hs_color[0], + s: stateObj.attributes.hs_color[1] / 100, + }; + } + } + } + + private _effectChanged(ev: CustomEvent) { + const newVal = ev.detail.value; + + if (!newVal || this.stateObj!.attributes.effect === newVal) { + return; + } + + this.hass.callService("light", "turn_on", { + entity_id: this.stateObj!.entity_id, + effect: newVal, + }); + } + + private _brightnessSliderChanged(ev: CustomEvent) { + const bri = parseInt((ev.target as any).value, 10); + + if (isNaN(bri)) { + return; + } + + this.hass.callService("light", "turn_on", { + entity_id: this.stateObj!.entity_id, + brightness: bri, + }); + } + + private _ctSliderChanged(ev: CustomEvent) { + const ct = parseInt((ev.target as any).value, 10); + + if (isNaN(ct)) { + return; + } + + this.hass.callService("light", "turn_on", { + entity_id: this.stateObj!.entity_id, + color_temp: ct, + }); + } + + private _wvSliderChanged(ev: CustomEvent) { + const wv = parseInt((ev.target as any).value, 10); + + if (isNaN(wv)) { + return; + } + + this.hass.callService("light", "turn_on", { + entity_id: this.stateObj!.entity_id, + white_value: wv, + }); + } + + private _segmentClick() { + if (this._hueSegments === 24 && this._saturationSegments === 8) { + this._hueSegments = 0; + this._saturationSegments = 0; + } else { + this._hueSegments = 24; + this._saturationSegments = 8; + } + } + + /** + * Called when a new color has been picked. + * should be throttled with the 'throttle=' attribute of the color picker + */ + private _colorPicked(ev: CustomEvent) { + this.hass.callService("light", "turn_on", { + entity_id: this.stateObj!.entity_id, + hs_color: [ev.detail.hs.h, ev.detail.hs.s * 100], + }); + } + + static get styles(): CSSResult { + return css` + .content { + display: flex; + flex-direction: column; + align-items: center; + } + + .content.is-on { + margin-top: -16px; + } + + .content > * { + width: 100%; + max-height: 84px; + overflow: hidden; + padding-top: 16px; + } + + .color_temp { + --ha-slider-background: -webkit-linear-gradient( + right, + rgb(255, 160, 0) 0%, + white 50%, + rgb(166, 209, 255) 100% + ); + /* The color temp minimum value shouldn't be rendered differently. It's not "off". */ + --paper-slider-knob-start-border-color: var(--primary-color); + } + + .segmentationContainer { + position: relative; + max-height: 500px; + } + + ha-color-picker { + --ha-color-picker-wheel-borderwidth: 5; + --ha-color-picker-wheel-bordercolor: white; + --ha-color-picker-wheel-shadow: none; + --ha-color-picker-marker-borderwidth: 2; + --ha-color-picker-marker-bordercolor: white; + } + + .segmentationButton { + position: absolute; + top: 5%; + color: var(--secondary-text-color); + } + + paper-item { + cursor: pointer; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "more-info-light": MoreInfoLight; + } +} diff --git a/src/types.ts b/src/types.ts index 57a945a993..4b0af2a890 100644 --- a/src/types.ts +++ b/src/types.ts @@ -254,6 +254,10 @@ export type LightEntity = HassEntityBase & { friendly_name: string; brightness: number; hs_color: number[]; + color_temp: number; + white_value: number; + effect?: string; + effect_list: string[] | null; }; }; From 39f24c41ad05d8d33094278fd5c7b88698239327 Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Mon, 17 Aug 2020 11:24:19 -0500 Subject: [PATCH 29/38] Media More Info: Convert to Lit Element (#6619) * lit element * Remove Properties * review comments * This should be somewhat better. --- src/data/media-player.ts | 5 + .../controls/more-info-media_player.js | 421 ------------------ .../controls/more-info-media_player.ts | 381 ++++++++++++++++ .../lovelace/cards/hui-media-control-card.ts | 6 +- src/types.ts | 6 + 5 files changed, 393 insertions(+), 426 deletions(-) delete mode 100644 src/dialogs/more-info/controls/more-info-media_player.js create mode 100644 src/dialogs/more-info/controls/more-info-media_player.ts diff --git a/src/data/media-player.ts b/src/data/media-player.ts index 1f716cbee1..71a2939716 100644 --- a/src/data/media-player.ts +++ b/src/data/media-player.ts @@ -21,6 +21,11 @@ export interface MediaPlayerThumbnail { content: string; } +export interface ControlButton { + icon: string; + action: string; +} + export const getCurrentProgress = (stateObj: HassEntity): number => { let progress = stateObj.attributes.media_position; diff --git a/src/dialogs/more-info/controls/more-info-media_player.js b/src/dialogs/more-info/controls/more-info-media_player.js deleted file mode 100644 index 2e45403793..0000000000 --- a/src/dialogs/more-info/controls/more-info-media_player.js +++ /dev/null @@ -1,421 +0,0 @@ -import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "../../../components/ha-icon-button"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-listbox/paper-listbox"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import { isComponentLoaded } from "../../../common/config/is_component_loaded"; -import { attributeClassNames } from "../../../common/entity/attribute_class_names"; -import { computeRTLDirection } from "../../../common/util/compute_rtl"; -import "../../../components/ha-paper-dropdown-menu"; -import "../../../components/ha-paper-slider"; -import "../../../components/ha-icon"; -import { EventsMixin } from "../../../mixins/events-mixin"; -import LocalizeMixin from "../../../mixins/localize-mixin"; -import HassMediaPlayerEntity from "../../../util/hass-media-player-model"; - -/* - * @appliesMixin LocalizeMixin - * @appliesMixin EventsMixin - */ -class MoreInfoMediaPlayer extends LocalizeMixin(EventsMixin(PolymerElement)) { - static get template() { - return html` - - - -
-
-
- -
-
- -
-
- -
- - - -
-
- - - -
- -
- - - - - - -
- - - -
- - -
-
- `; - } - - static get properties() { - return { - hass: Object, - stateObj: Object, - playerObj: { - type: Object, - computed: "computePlayerObj(hass, stateObj)", - observer: "playerObjChanged", - }, - - ttsLoaded: { - type: Boolean, - computed: "computeTTSLoaded(hass)", - }, - - ttsMessage: { - type: String, - value: "", - }, - - rtl: { - type: String, - computed: "_computeRTLDirection(hass)", - }, - }; - } - - computePlayerObj(hass, stateObj) { - return new HassMediaPlayerEntity(hass, stateObj); - } - - playerObjChanged(newVal, oldVal) { - if (oldVal) { - setTimeout(() => { - this.fire("iron-resize"); - }, 500); - } - } - - computeClassNames(stateObj) { - return attributeClassNames(stateObj, ["volume_level"]); - } - - computeMuteVolumeIcon(playerObj) { - return playerObj.isMuted ? "hass:volume-off" : "hass:volume-high"; - } - - computeHideVolumeButtons(playerObj) { - return !playerObj.supportsVolumeButtons || playerObj.isOff; - } - - computeShowPlaybackControls(playerObj) { - return !playerObj.isOff && playerObj.hasMediaControl; - } - - computePlaybackControlIcon(playerObj) { - if (playerObj.isPlaying) { - return playerObj.supportsPause ? "hass:pause" : "hass:stop"; - } - if (playerObj.hasMediaControl || playerObj.isOff || playerObj.isIdle) { - if ( - playerObj.hasMediaControl && - playerObj.supportsPause && - !playerObj.isPaused - ) { - return "hass:play-pause"; - } - return playerObj.supportsPlay ? "hass:play" : null; - } - return ""; - } - - computeHidePowerButton(playerObj) { - return playerObj.isOff - ? !playerObj.supportsTurnOn - : !playerObj.supportsTurnOff; - } - - computeHideSelectSource(playerObj) { - return ( - playerObj.isOff || - !playerObj.supportsSelectSource || - !playerObj.sourceList - ); - } - - computeHideSelectSoundMode(playerObj) { - return ( - playerObj.isOff || - !playerObj.supportsSelectSoundMode || - !playerObj.soundModeList - ); - } - - computeHideTTS(ttsLoaded, playerObj) { - return !ttsLoaded || !playerObj.supportsPlayMedia; - } - - computeTTSLoaded(hass) { - return isComponentLoaded(hass, "tts"); - } - - handleTogglePower() { - this.playerObj.togglePower(); - } - - handlePrevious() { - this.playerObj.previousTrack(); - } - - handlePlaybackControl() { - this.playerObj.mediaPlayPause(); - } - - handleNext() { - this.playerObj.nextTrack(); - } - - handleSourceChanged(ev) { - if (!this.playerObj) return; - - const oldVal = this.playerObj.source; - const newVal = ev.detail.value; - - if (!newVal || oldVal === newVal) return; - - this.playerObj.selectSource(newVal); - } - - handleSoundModeChanged(ev) { - if (!this.playerObj) return; - - const oldVal = this.playerObj.soundMode; - const newVal = ev.detail.value; - - if (!newVal || oldVal === newVal) return; - - this.playerObj.selectSoundMode(newVal); - } - - handleVolumeTap() { - if (!this.playerObj.supportsVolumeMute) { - return; - } - this.playerObj.volumeMute(!this.playerObj.isMuted); - } - - handleVolumeTouchEnd(ev) { - /* when touch ends, we must prevent this from - * becoming a mousedown, up, click by emulation */ - ev.preventDefault(); - } - - handleVolumeUp() { - const obj = this.$.volumeUp; - this.handleVolumeWorker("volume_up", obj, true); - } - - handleVolumeDown() { - const obj = this.$.volumeDown; - this.handleVolumeWorker("volume_down", obj, true); - } - - handleVolumeWorker(service, obj, force) { - if (force || (obj !== undefined && obj.pointerDown)) { - this.playerObj.callService(service); - setTimeout(() => this.handleVolumeWorker(service, obj, false), 500); - } - } - - volumeSliderChanged(ev) { - const volPercentage = parseFloat(ev.target.value); - const volume = volPercentage > 0 ? volPercentage / 100 : 0; - this.playerObj.setVolume(volume); - } - - ttsCheckForEnter(ev) { - if (ev.keyCode === 13) this.sendTTS(); - } - - sendTTS() { - const services = this.hass.services.tts; - const serviceKeys = Object.keys(services).sort(); - let service; - let i; - - for (i = 0; i < serviceKeys.length; i++) { - if (serviceKeys[i].indexOf("_say") !== -1) { - service = serviceKeys[i]; - break; - } - } - - if (!service) { - return; - } - - this.hass.callService("tts", service, { - entity_id: this.stateObj.entity_id, - message: this.ttsMessage, - }); - this.ttsMessage = ""; - this.$.ttsInput.focus(); - } - - _computeRTLDirection(hass) { - return computeRTLDirection(hass); - } -} - -customElements.define("more-info-media_player", MoreInfoMediaPlayer); diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts new file mode 100644 index 0000000000..efa96dec86 --- /dev/null +++ b/src/dialogs/more-info/controls/more-info-media_player.ts @@ -0,0 +1,381 @@ +import "@polymer/paper-item/paper-item"; +import "@polymer/paper-listbox/paper-listbox"; +import "@polymer/paper-input/paper-input"; + +import { + css, + CSSResult, + html, + LitElement, + property, + TemplateResult, + customElement, + query, +} from "lit-element"; +import { computeRTLDirection } from "../../../common/util/compute_rtl"; +import { HomeAssistant, MediaEntity } from "../../../types"; +import { supportsFeature } from "../../../common/entity/supports-feature"; +import { UNAVAILABLE_STATES, UNAVAILABLE, UNKNOWN } from "../../../data/entity"; +import { + SUPPORT_TURN_ON, + SUPPORT_TURN_OFF, + SUPPORTS_PLAY, + SUPPORT_PREVIOUS_TRACK, + SUPPORT_PAUSE, + SUPPORT_STOP, + SUPPORT_NEXT_TRACK, + SUPPORT_VOLUME_MUTE, + SUPPORT_VOLUME_SET, + SUPPORT_VOLUME_BUTTONS, + SUPPORT_SELECT_SOURCE, + SUPPORT_SELECT_SOUND_MODE, + SUPPORT_PLAY_MEDIA, + ControlButton, +} from "../../../data/media-player"; +import { isComponentLoaded } from "../../../common/config/is_component_loaded"; + +import "../../../components/ha-paper-dropdown-menu"; +import "../../../components/ha-icon-button"; +import "../../../components/ha-slider"; +import "../../../components/ha-icon"; + +@customElement("more-info-media_player") +class MoreInfoMediaPlayer extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public stateObj?: MediaEntity; + + @query("#ttsInput") private _ttsInput?: HTMLInputElement; + + protected render(): TemplateResult { + if (!this.stateObj) { + return html``; + } + + const controls = this._getControls(); + const stateObj = this.stateObj; + + return html` + ${!controls + ? "" + : html` +
+ ${controls!.map( + (control) => html` + + ` + )} +
+ `} + ${(supportsFeature(stateObj, SUPPORT_VOLUME_SET) || + supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS)) && + ![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) + ? html` +
+ ${supportsFeature(stateObj, SUPPORT_VOLUME_MUTE) + ? html` + + ` + : ""} + ${supportsFeature(stateObj, SUPPORT_VOLUME_SET) + ? html` + + ` + : supportsFeature(stateObj, SUPPORT_VOLUME_BUTTONS) + ? html` + + + ` + : ""} +
+ ` + : ""} + ${stateObj.state !== "off" && + supportsFeature(stateObj, SUPPORT_SELECT_SOURCE) && + stateObj.attributes.source_list?.length + ? html` +
+ + + + ${stateObj.attributes.source_list!.map( + (source) => + html` + ${source} + ` + )} + + +
+ ` + : ""} + ${supportsFeature(stateObj, SUPPORT_SELECT_SOUND_MODE) && + stateObj.attributes.sound_mode_list?.length + ? html` +
+ + + + ${stateObj.attributes.sound_mode_list.map( + (mode) => html` + ${mode} + ` + )} + + +
+ ` + : ""} + ${isComponentLoaded(this.hass, "tts") && + supportsFeature(stateObj, SUPPORT_PLAY_MEDIA) + ? html` +
+ + +
+
+ ` + : ""} + `; + } + + static get styles(): CSSResult { + return css` + ha-icon-button[action="turn_off"], + ha-icon-button[action="turn_on"], + ha-slider, + #ttsInput { + flex-grow: 1; + } + + .volume, + .controls, + .source-input, + .sound-input, + .tts { + display: flex; + align-items: center; + justify-content: space-between; + } + + .source-input ha-icon, + .sound-input ha-icon { + padding: 7px; + margin-top: 24px; + } + + .source-input ha-paper-dropdown-menu, + .sound-input ha-paper-dropdown-menu { + margin-left: 10px; + flex-grow: 1; + } + + paper-item { + cursor: pointer; + } + `; + } + + private _getControls(): ControlButton[] | undefined { + const stateObj = this.stateObj; + + if (!stateObj) { + return undefined; + } + + const state = stateObj.state; + + if (UNAVAILABLE_STATES.includes(state)) { + return undefined; + } + + if (state === "off") { + return supportsFeature(stateObj, SUPPORT_TURN_ON) + ? [ + { + icon: "hass:power", + action: "turn_on", + }, + ] + : undefined; + } + + if (state === "idle") { + return supportsFeature(stateObj, SUPPORTS_PLAY) + ? [ + { + icon: "hass:play", + action: "media_play", + }, + ] + : undefined; + } + + const buttons: ControlButton[] = []; + + if (supportsFeature(stateObj, SUPPORT_TURN_OFF)) { + buttons.push({ + icon: "hass:power", + action: "turn_off", + }); + } + + if (supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK)) { + buttons.push({ + icon: "hass:skip-previous", + action: "media_previous_track", + }); + } + + if ( + (state === "playing" && + (supportsFeature(stateObj, SUPPORT_PAUSE) || + supportsFeature(stateObj, SUPPORT_STOP))) || + (state === "paused" && supportsFeature(stateObj, SUPPORTS_PLAY)) + ) { + buttons.push({ + icon: + state !== "playing" + ? "hass:play" + : supportsFeature(stateObj, SUPPORT_PAUSE) + ? "hass:pause" + : "hass:stop", + action: "media_play_pause", + }); + } + + if (supportsFeature(stateObj, SUPPORT_NEXT_TRACK)) { + buttons.push({ + icon: "hass:skip-next", + action: "media_next_track", + }); + } + + return buttons.length > 0 ? buttons : undefined; + } + + private _handleClick(e: MouseEvent): void { + this.hass!.callService( + "media_player", + (e.currentTarget! as HTMLElement).getAttribute("action")!, + { + entity_id: this.stateObj!.entity_id, + } + ); + } + + private _toggleMute() { + this.hass!.callService("media_player", "volume_mute", { + entity_id: this.stateObj!.entity_id, + is_volume_muted: !this.stateObj!.attributes.is_volume_muted, + }); + } + + private _selectedValueChanged(e: Event): void { + this.hass!.callService("media_player", "volume_set", { + entity_id: this.stateObj!.entity_id, + volume_level: + Number((e.currentTarget! as HTMLElement).getAttribute("value")!) / 100, + }); + } + + private _handleSourceChanged(e: CustomEvent) { + const newVal = e.detail.value; + + if (!newVal || this.stateObj!.attributes.source === newVal) return; + + this.hass.callService("media_player", "select_source", { + source: newVal, + }); + } + + private _handleSoundModeChanged(e: CustomEvent) { + const newVal = e.detail.value; + + if (!newVal || this.stateObj?.attributes.sound_mode === newVal) return; + + this.hass.callService("media_player", "select_sound_mode", { + sound_mode: newVal, + }); + } + + private _ttsCheckForEnter(e: KeyboardEvent) { + if (e.keyCode === 13) this._sendTTS(); + } + + private _sendTTS() { + const ttsInput = this._ttsInput; + if (!ttsInput) { + return; + } + + const services = this.hass.services.tts; + const serviceKeys = Object.keys(services).sort(); + + const service = serviceKeys.find((key) => key.indexOf("_say") !== -1); + + if (!service) { + return; + } + + this.hass.callService("tts", service, { + entity_id: this.stateObj!.entity_id, + message: ttsInput.value, + }); + ttsInput.value = ""; + } +} + +declare global { + interface HTMLElementTagNameMap { + "more-info-media_player": MoreInfoMediaPlayer; + } +} diff --git a/src/panels/lovelace/cards/hui-media-control-card.ts b/src/panels/lovelace/cards/hui-media-control-card.ts index 51528d8d32..cb6df43058 100644 --- a/src/panels/lovelace/cards/hui-media-control-card.ts +++ b/src/panels/lovelace/cards/hui-media-control-card.ts @@ -38,6 +38,7 @@ import { SUPPORT_STOP, SUPPORT_TURN_OFF, SUPPORT_TURN_ON, + ControlButton, } from "../../../data/media-player"; import type { HomeAssistant, MediaEntity } from "../../../types"; import { contrast } from "../common/color/contrast"; @@ -157,11 +158,6 @@ const customGenerator = (colors: Swatch[]) => { return [foregroundColor, backgroundColor.hex]; }; -interface ControlButton { - icon: string; - action: string; -} - @customElement("hui-media-control-card") export class HuiMediaControlCard extends LitElement implements LovelaceCard { public static async getConfigElement(): Promise { diff --git a/src/types.ts b/src/types.ts index 4b0af2a890..7639f1ea43 100644 --- a/src/types.ts +++ b/src/types.ts @@ -287,6 +287,12 @@ export type MediaEntity = HassEntityBase & { media_title: string; icon?: string; entity_picture_local?: string; + is_volume_muted?: boolean; + volume_level?: number; + source?: string; + source_list?: string[]; + sound_mode?: string; + sound_mode_list?: string[]; }; state: | "playing" From c4d8aba5c8fbcfe48a0e36f396e4b3d7cf9da952 Mon Sep 17 00:00:00 2001 From: Charles Garwood Date: Mon, 17 Aug 2020 13:54:03 -0400 Subject: [PATCH 30/38] Add OZW Refresh Node Dialog (#6530) --- src/data/ozw.ts | 97 ++++++- .../ozw/ha-device-info-ozw.ts | 48 +++- .../ozw/dialog-ozw-refresh-node.ts | 272 ++++++++++++++++++ .../ozw/show-dialog-ozw-refresh-node.ts | 22 ++ src/translations/en.json | 35 ++- 5 files changed, 459 insertions(+), 15 deletions(-) create mode 100644 src/panels/config/integrations/integration-panels/ozw/dialog-ozw-refresh-node.ts create mode 100644 src/panels/config/integrations/integration-panels/ozw/show-dialog-ozw-refresh-node.ts diff --git a/src/data/ozw.ts b/src/data/ozw.ts index 491b0168a2..cbef2a8dbc 100644 --- a/src/data/ozw.ts +++ b/src/data/ozw.ts @@ -1,4 +1,10 @@ import { HomeAssistant } from "../types"; +import { DeviceRegistryEntry } from "./device_registry"; + +export interface OZWNodeIdentifiers { + ozw_instance: number; + node_id: number; +} export interface OZWDevice { node_id: number; @@ -7,15 +13,102 @@ export interface OZWDevice { is_failed: boolean; is_zwave_plus: boolean; ozw_instance: number; + event: string; } +export interface OZWDeviceMetaDataResponse { + node_id: number; + ozw_instance: number; + metadata: OZWDeviceMetaData; +} + +export interface OZWDeviceMetaData { + OZWInfoURL: string; + ZWAProductURL: string; + ProductPic: string; + Description: string; + ProductManualURL: string; + ProductPageURL: string; + InclusionHelp: string; + ExclusionHelp: string; + ResetHelp: string; + WakeupHelp: string; + ProductSupportURL: string; + Frequency: string; + Name: string; + ProductPicBase64: string; +} + +export const nodeQueryStages = [ + "ProtocolInfo", + "Probe", + "WakeUp", + "ManufacturerSpecific1", + "NodeInfo", + "NodePlusInfo", + "ManufacturerSpecific2", + "Versions", + "Instances", + "Static", + "CacheLoad", + "Associations", + "Neighbors", + "Session", + "Dynamic", + "Configuration", + "Complete", +]; + +export const getIdentifiersFromDevice = function ( + device: DeviceRegistryEntry +): OZWNodeIdentifiers | undefined { + if (!device) { + return undefined; + } + + const ozwIdentifier = device.identifiers.find( + (identifier) => identifier[0] === "ozw" + ); + if (!ozwIdentifier) { + return undefined; + } + + const identifiers = ozwIdentifier[1].split("."); + return { + node_id: parseInt(identifiers[1]), + ozw_instance: parseInt(identifiers[0]), + }; +}; + export const fetchOZWNodeStatus = ( hass: HomeAssistant, - ozw_instance: string, - node_id: string + ozw_instance: number, + node_id: number ): Promise => hass.callWS({ type: "ozw/node_status", ozw_instance: ozw_instance, node_id: node_id, }); + +export const fetchOZWNodeMetadata = ( + hass: HomeAssistant, + ozw_instance: number, + node_id: number +): Promise => + hass.callWS({ + type: "ozw/node_metadata", + ozw_instance: ozw_instance, + node_id: node_id, + }); + +export const refreshNodeInfo = ( + hass: HomeAssistant, + ozw_instance: number, + node_id: number +): Promise => + hass.callWS({ + type: "ozw/refresh_node_info", + ozw_instance: ozw_instance, + node_id: node_id, + }); diff --git a/src/panels/config/devices/device-detail/integration-elements/ozw/ha-device-info-ozw.ts b/src/panels/config/devices/device-detail/integration-elements/ozw/ha-device-info-ozw.ts index b82ba363f0..2197fe689b 100644 --- a/src/panels/config/devices/device-detail/integration-elements/ozw/ha-device-info-ozw.ts +++ b/src/panels/config/devices/device-detail/integration-elements/ozw/ha-device-info-ozw.ts @@ -12,7 +12,13 @@ import { import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; import { haStyle } from "../../../../../../resources/styles"; import { HomeAssistant } from "../../../../../../types"; -import { OZWDevice, fetchOZWNodeStatus } from "../../../../../../data/ozw"; +import { + OZWDevice, + fetchOZWNodeStatus, + getIdentifiersFromDevice, + OZWNodeIdentifiers, +} from "../../../../../../data/ozw"; +import { showOZWRefreshNodeDialog } from "../../../../integrations/integration-panels/ozw/show-dialog-ozw-refresh-node"; @customElement("ha-device-info-ozw") export class HaDeviceInfoOzw extends LitElement { @@ -20,26 +26,34 @@ export class HaDeviceInfoOzw extends LitElement { @property() public device!: DeviceRegistryEntry; + @property() + private node_id = 0; + + @property() + private ozw_instance = 1; + @internalProperty() private _ozwDevice?: OZWDevice; protected updated(changedProperties: PropertyValues) { if (changedProperties.has("device")) { - this._fetchNodeDetails(this.device); + const identifiers: + | OZWNodeIdentifiers + | undefined = getIdentifiersFromDevice(this.device); + if (!identifiers) { + return; + } + this.ozw_instance = identifiers.ozw_instance; + this.node_id = identifiers.node_id; + + this._fetchNodeDetails(); } } - protected async _fetchNodeDetails(device) { - const ozwIdentifier = device.identifiers.find( - (identifier) => identifier[0] === "ozw" - ); - if (!ozwIdentifier) { - return; - } - const identifiers = ozwIdentifier[1].split("."); + protected async _fetchNodeDetails() { this._ozwDevice = await fetchOZWNodeStatus( this.hass, - identifiers[0], - identifiers[1] + this.ozw_instance, + this.node_id ); } @@ -69,9 +83,19 @@ export class HaDeviceInfoOzw extends LitElement { ? this.hass.localize("ui.common.yes") : this.hass.localize("ui.common.no")}
+ + Refresh Node + `; } + private async _refreshNodeClicked() { + showOZWRefreshNodeDialog(this, { + node_id: this.node_id, + ozw_instance: this.ozw_instance, + }); + } + static get styles(): CSSResult[] { return [ haStyle, diff --git a/src/panels/config/integrations/integration-panels/ozw/dialog-ozw-refresh-node.ts b/src/panels/config/integrations/integration-panels/ozw/dialog-ozw-refresh-node.ts new file mode 100644 index 0000000000..6f86fbc7bc --- /dev/null +++ b/src/panels/config/integrations/integration-panels/ozw/dialog-ozw-refresh-node.ts @@ -0,0 +1,272 @@ +import { + CSSResult, + customElement, + html, + LitElement, + property, + internalProperty, + TemplateResult, + PropertyValues, + css, +} from "lit-element"; +import "../../../../../components/ha-code-editor"; +import "../../../../../components/ha-circular-progress"; +import { createCloseHeading } from "../../../../../components/ha-dialog"; +import { haStyleDialog } from "../../../../../resources/styles"; +import { HomeAssistant } from "../../../../../types"; +import { OZWRefreshNodeDialogParams } from "./show-dialog-ozw-refresh-node"; + +import { + fetchOZWNodeMetadata, + OZWDeviceMetaData, + OZWDevice, + nodeQueryStages, +} from "../../../../../data/ozw"; + +@customElement("dialog-ozw-refresh-node") +class DialogOZWRefreshNode extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @internalProperty() private _node_id?: number; + + @internalProperty() private _ozw_instance = 1; + + @internalProperty() private _nodeMetaData?: OZWDeviceMetaData; + + @internalProperty() private _node?: OZWDevice; + + @internalProperty() private _active = false; + + @internalProperty() private _complete = false; + + private _refreshDevicesTimeoutHandle?: number; + + private _subscribed?: Promise<() => Promise>; + + public disconnectedCallback(): void { + super.disconnectedCallback(); + this._unsubscribe(); + } + + protected updated(changedProperties: PropertyValues): void { + super.update(changedProperties); + if (changedProperties.has("node_id")) { + this._fetchData(); + } + } + + private async _fetchData() { + if (!this._node_id) { + return; + } + const metaDataResponse = await fetchOZWNodeMetadata( + this.hass, + this._ozw_instance, + this._node_id + ); + + this._nodeMetaData = metaDataResponse.metadata; + } + + public async showDialog(params: OZWRefreshNodeDialogParams): Promise { + this._node_id = params.node_id; + this._ozw_instance = params.ozw_instance; + this._fetchData(); + } + + protected render(): TemplateResult { + if (!this._node_id) { + return html``; + } + + return html` + + ${this._complete + ? html` +

+ ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.complete" + )} +

+ + ${this.hass.localize("ui.common.close")} + + ` + : html` + ${this._active + ? html` +
+ +
+

+ + ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.refreshing_description" + )} + +

+ ${this._node + ? html` +

+ ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.node_status" + )}: + ${this._node.node_query_stage} + (${this.hass.localize( + "ui.panel.config.ozw.refresh_node.step" + )} + ${nodeQueryStages.indexOf( + this._node.node_query_stage + ) + 1}/17) +

+

+ + ${this.hass.localize( + "ui.panel.config.ozw.node_query_stages." + + this._node.node_query_stage.toLowerCase() + )} +

+ ` + : ``} +
+
+ ` + : html` + ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.description" + )} +

+ ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.battery_note" + )} +

+ `} + ${this._nodeMetaData?.WakeupHelp !== "" + ? html` + + ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.wakeup_header" + )} + ${this._nodeMetaData!.Name} + +
+ ${this._nodeMetaData!.WakeupHelp} +
+ + ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.wakeup_instructions_source" + )} + +
+ ` + : ""} + ${!this._active + ? html` + + ${this.hass.localize( + "ui.panel.config.ozw.refresh_node.start_refresh_button" + )} + + ` + : html``} + `} +
+ `; + } + + private _startRefresh(): void { + this._subscribe(); + } + + private _handleMessage(message: any): void { + if (message.type === "node_updated") { + this._node = message; + if (message.node_query_stage === "Complete") { + this._unsubscribe(); + this._complete = true; + } + } + } + + private _unsubscribe(): void { + this._active = false; + if (this._refreshDevicesTimeoutHandle) { + clearTimeout(this._refreshDevicesTimeoutHandle); + } + if (this._subscribed) { + this._subscribed.then((unsub) => unsub()); + this._subscribed = undefined; + } + } + + private _subscribe(): void { + if (!this.hass) { + return; + } + this._active = true; + this._subscribed = this.hass.connection.subscribeMessage( + (message) => this._handleMessage(message), + { + type: "ozw/refresh_node_info", + node_id: this._node_id, + ozw_instance: this._ozw_instance, + } + ); + this._refreshDevicesTimeoutHandle = window.setTimeout( + () => this._unsubscribe(), + 120000 + ); + } + + private _close(): void { + this._complete = false; + this._node_id = undefined; + this._node = undefined; + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + blockquote { + display: block; + background-color: #ddd; + padding: 8px; + margin: 8px 0; + font-size: 0.9em; + } + + blockquote em { + font-size: 0.9em; + margin-top: 6px; + } + + .flex-container { + display: flex; + align-items: center; + } + + .flex-container ha-circular-progress { + margin-right: 20px; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-ozw-refresh-node": DialogOZWRefreshNode; + } +} diff --git a/src/panels/config/integrations/integration-panels/ozw/show-dialog-ozw-refresh-node.ts b/src/panels/config/integrations/integration-panels/ozw/show-dialog-ozw-refresh-node.ts new file mode 100644 index 0000000000..0c956f9ffe --- /dev/null +++ b/src/panels/config/integrations/integration-panels/ozw/show-dialog-ozw-refresh-node.ts @@ -0,0 +1,22 @@ +import { fireEvent } from "../../../../../common/dom/fire_event"; + +export interface OZWRefreshNodeDialogParams { + ozw_instance: number; + node_id: number; +} + +export const loadRefreshNodeDialog = () => + import( + /* webpackChunkName: "dialog-ozw-refresh-node" */ "./dialog-ozw-refresh-node" + ); + +export const showOZWRefreshNodeDialog = ( + element: HTMLElement, + refreshNodeDialogParams: OZWRefreshNodeDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-ozw-refresh-node", + dialogImport: loadRefreshNodeDialog, + dialogParams: refreshNodeDialogParams, + }); +}; diff --git a/src/translations/en.json b/src/translations/en.json index 48d51fa5aa..41f54a7386 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1066,7 +1066,9 @@ "label": "Repeat", "type_select": "Repeat type", "type": { - "count": { "label": "Count" }, + "count": { + "label": "Count" + }, "while": { "label": "While", "conditions": "While conditions" @@ -1628,6 +1630,37 @@ "zwave_info": "Z-Wave Info", "stage": "Stage", "node_failed": "Node Failed" + }, + "node_query_stages": { + "protocolinfo": "Obtaining basic Z-Wave capabilities of this node from the controller", + "probe": "Checking if the node is awake/alive", + "wakeup": "Setting up support for wakeup queues and messages", + "manufacturerspecific1": "Obtaining manufacturer and product ID codes from the node", + "nodeinfo": "Obtaining supported command classes from the node", + "nodeplusinfo": "Obtaining Z-Wave+ information from the node", + "manufacturerspecific2": "Obtaining additional manufacturer and product ID codes from the node", + "versions": "Obtaining information about firmware and command class versions", + "instances": "Obtaining details about what instances or channels a device supports", + "static": "Obtaining static values from the device", + "cacheload": "Loading information from the OpenZWave cache file. Battery nodes will stay at this stage until the node wakes up.", + "associations": "Refreshing association groups and memberships", + "neighbors": "Obtaining a list of the node's neighbors", + "session": "Obtaining infrequently changing values from the node", + "dynamic": "Obtaining frequently changing values from the node", + "configuration": "Obtaining configuration values from the node", + "complete": "Interview process is complete" + }, + "refresh_node": { + "title": "Refresh Node Information", + "complete": "Node Refresh Complete", + "description": "This will tell OpenZWave to re-interview a node and update the node's command classes, capabilities, and values.", + "battery_note": "If the node is battery powered, be sure to wake it before proceeding", + "wakeup_header": "Wakeup Instructions for", + "wakeup_instructions_source": "Wakeup instructions are sourced from the OpenZWave community device database.", + "start_refresh_button": "Start Refresh", + "refreshing_description": "Refreshing node information...", + "node_status": "Node Status", + "step": "Step" } }, "zha": { From f1503f871bc2fb508402e4b2a250221c89cad630 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Tue, 18 Aug 2020 00:32:11 +0000 Subject: [PATCH 31/38] [ci skip] Translation update --- translations/frontend/el.json | 259 ++++++++++++++++++++++++++++++---- translations/frontend/en.json | 31 ++++ translations/frontend/fy.json | 17 ++- translations/frontend/he.json | 8 +- translations/frontend/it.json | 4 +- translations/frontend/ko.json | 78 ++++++++-- translations/frontend/nn.json | 43 ++++-- translations/frontend/pt.json | 1 + 8 files changed, 382 insertions(+), 59 deletions(-) diff --git a/translations/frontend/el.json b/translations/frontend/el.json index 0b8152cc24..10dd95d0cf 100644 --- a/translations/frontend/el.json +++ b/translations/frontend/el.json @@ -219,6 +219,8 @@ "stopped": "Σταμάτησε" }, "default": { + "off": "Μη Ενεργό", + "on": "Ενεργό", "unavailable": "Μη Διαθέσιμο", "unknown": "Άγνωστη" }, @@ -401,7 +403,9 @@ }, "humidifier": { "humidity": "Επιθυμητή υγρασία", - "mode": "Λειτουργία" + "mode": "Λειτουργία", + "on_entity": "{name} ενεργοποιημένο", + "target_humidity_entity": "{name} στόχος υγρασίας" }, "light": { "brightness": "Φωτεινότητα", @@ -427,6 +431,7 @@ }, "script": { "cancel": "Ακύρωση", + "cancel_multiple": "Ακύρωση {αριθμός}", "execute": "Εκτέλεση" }, "service": { @@ -489,11 +494,16 @@ } }, "common": { + "and": "και", + "back": "Πίσω", "cancel": "Ακύρωση", "close": "Κλείστε", "delete": "Διαγραφή", + "error_required": "Υποχρεωτικό", "loading": "Φόρτωση", + "menu": "Μενού", "no": "Όχι", + "overflow_menu": "Μενού υπερχείλισης", "save": "Αποθήκευση", "successfully_deleted": "Η διαγραφή ολοκληρώθηκε με επιτυχία", "successfully_saved": "Αποθηκεύτηκε με επιτυχία", @@ -515,6 +525,7 @@ "show_areas": "Εμφάνιση περιοχών" }, "data-table": { + "no-data": "Δεν υπάρχουν δεδομένα", "search": "Αναζήτηση" }, "date-range-picker": { @@ -525,6 +536,7 @@ "device-picker": { "clear": "Καθαρός", "device": "Συσκευή", + "no_area": "Καμία περιοχή", "show_devices": "Εμφάνιση συσκευών", "toggle": "Εναλλαγή" }, @@ -572,7 +584,8 @@ "entity_id": "Αναγνωριστικό οντότητας", "unavailable": "Αυτή η οντότητα δεν είναι προς το παρόν διαθέσιμη.", "update": "Ενημέρωση" - } + }, + "no_unique_id": "Αυτή η οντότητα δεν έχει μοναδικό αναγνωριστικό, επομένως δεν είναι δυνατή η διαχείριση των ρυθμίσεών της από το περιβάλλον χρήστη." }, "generic": { "cancel": "Ακύρωση", @@ -585,10 +598,15 @@ "datetime": "Ημερομηνία και ώρα", "time": "Ώρα" }, + "input_number": { + "step": "Μέγεθος βήματος" + }, "input_text": { "max": "Μέγιστο μήκος", "min": "Ελάχιστο μήκος" - } + }, + "platform_not_loaded": "Η ενσωμάτωση {platform} δεν έχει φορτωθεί. Προσθέστε το στη διαμόρφωσή σας είτε προσθέτοντας 'default_config:' ή '' {platform} : ''.", + "yaml_not_editable": "Δεν είναι δυνατή η επεξεργασία των ρυθμίσεων αυτής της οντότητας από το περιβάλλον χρήστη. Μόνο οντότητες που έχουν δημιουργηθεί από το περιβάλλον χρήστη μπορούν να διαμορφωθούν από το περιβάλλον χρήστη." }, "more_info_control": { "dismiss": "Κλείσιμο διαλόγου.", @@ -612,6 +630,16 @@ "title": "Οδηγίες Ενημέρωσης" } }, + "mqtt_device_debug_info": { + "deserialize": "Προσπάθεια ανάλυσης μηνυμάτων MQTT ως JSON", + "entities": "Οντότητες", + "no_entities": "Δεν υπάρχουν οντότητες", + "no_triggers": "Δεν υπάρχουν εναύσματα", + "payload_display": "Εμφάνιση ωφέλιμου φορτίου", + "recent_messages": "{n} πιο πρόσφατα ληφθέντα μηνύματα", + "show_as_yaml": "Εμφάνιση ως YAML", + "title": "Πληροφορίες εντοπισμού σφαλμάτων {device}" + }, "options_flow": { "form": { "header": "Επιλογές" @@ -633,8 +661,10 @@ "add": "Προσθήκη συσκευών", "clusters": "Διαχείριση συμπλεγμάτων", "reconfigure": "Ρυθμίστε Ξανά Τη Συσκευή", - "remove": "Κατάργηση συσκευής" + "remove": "Κατάργηση συσκευής", + "zigbee_information": "Υπογραφή συσκευής Zigbee" }, + "device_signature": "Υπογραφή συσκευής Zigbee", "last_seen": "Εθεάθη τελευταία", "manuf": "από τον {manufacturer}", "no_area": "Καμία περιοχή", @@ -643,7 +673,8 @@ "services": { "reconfigure": "Ρυθμίστε ξανά τη συσκευή ZHA (θεραπεία συσκευής). Χρησιμοποιήστε αυτήν την επιλογή εάν αντιμετωπίζετε προβλήματα με τη συσκευή. Εάν η συγκεκριμένη συσκευή τροφοδοτείται από μπαταρία παρακαλώ βεβαιωθείτε ότι είναι ενεργοποιημένη και δέχεται εντολές όταν χρησιμοποιείτε αυτή την υπηρεσία.", "remove": "Καταργήστε μια συσκευή από το δίκτυο Zigbee.", - "updateDeviceName": "Ορίστε ένα προσαρμοσμένο όνομα γι αυτήν τη συσκευή στο μητρώο συσκευών." + "updateDeviceName": "Ορίστε ένα προσαρμοσμένο όνομα γι αυτήν τη συσκευή στο μητρώο συσκευών.", + "zigbee_information": "Δείτε τις πληροφορίες Zigbee για τη συσκευή." }, "unknown": "Άγνωστη", "zha_device_card": { @@ -674,9 +705,15 @@ "notification_toast": { "connection_lost": "Η σύνδεση χάθηκε. Επανασύνδεση…", "service_call_failed": "Απέτυχε η κλήση στην υπηρεσία {service}.", + "started": "Το Home Assistant έχει ξεκινήσει!", + "starting": "Το Home Assistant ξεκινά, ενδέχεται να μην είναι ακόμη διαθέσιμα όλα.", "triggered": "Ενεργοποιήθηκε το {name}" }, "panel": { + "calendar": { + "my_calendars": "Τα ημερολόγιά μου", + "today": "Σήμερα" + }, "config": { "advanced_mode": { "hint_enable": "Λείπουν επιλογές ρύθμισης παραμέτρων; Ενεργοποίηση σύνθετης λειτουργίας", @@ -694,8 +731,12 @@ }, "description": "Επισκόπηση όλων των περιοχών στο σπίτι σας.", "editor": { + "area_id": "Αναγνωριστικό περιοχής", "create": "Δημιουργία", "delete": "Διαγραφή", + "name": "Ονομασία", + "name_required": "Απαιτείται όνομα", + "unknown_error": "Άγνωστο σφάλμα", "update": "Ενημέρωση" }, "picker": { @@ -703,7 +744,8 @@ "header": "Περιοχή Μητρώου", "integrations_page": "Σελίδα ενσωματώσεων", "introduction": "Οι περιοχές χρησιμοποιούνται για την οργάνωση της τοποθεσίας των συσκευών. Αυτές οι πληροφορίες θα χρησιμοποιηθούν σε όλο το Home Assistant για να σας βοηθήσουν στην οργάνωση της διασύνδεσης, των αδειών και των ενσωματώσεων σας σε άλλα συστήματα.", - "introduction2": "Για να τοποθετήσετε συσκευές σε μια περιοχή, χρησιμοποιήστε τον παρακάτω σύνδεσμο για να μεταβείτε στη σελίδα ενοποιήσεων και στη συνέχεια κάντε κλικ στην ρυθμισμένη ενοποίηση για να μεταβείτε στις κάρτες της συσκευής." + "introduction2": "Για να τοποθετήσετε συσκευές σε μια περιοχή, χρησιμοποιήστε τον παρακάτω σύνδεσμο για να μεταβείτε στη σελίδα ενοποιήσεων και στη συνέχεια κάντε κλικ στην ρυθμισμένη ενοποίηση για να μεταβείτε στις κάρτες της συσκευής.", + "no_areas": "Φαίνεται ότι δεν έχετε περιοχές ακόμα!" } }, "automation": { @@ -721,6 +763,15 @@ "name": "Ενέργεια", "type_select": "Τύπος ενέργειας", "type": { + "choose": { + "add_option": "Προσθήκη επιλογής", + "conditions": "Συνθήκες", + "default": "Προεπιλεγμένες ενέργειες", + "label": "Επιλέξτε", + "option": "Επιλογή {αριθμός}", + "remove_option": "Κατάργηση επιλογής", + "sequence": "Ενέργειες" + }, "condition": { "label": "Προϋπόθεση" }, @@ -729,6 +780,7 @@ "label": "Καθυστέρηση" }, "device_id": { + "action": "Ενέργεια", "extra_fields": { "code": "Κώδικας" }, @@ -739,6 +791,24 @@ "label": "Εκκίνηση συμβάντος", "service_data": "Δεδομένα υπηρεσίας" }, + "repeat": { + "label": "Επανάληψη", + "sequence": "Ενέργειες", + "type_select": "Επανάληψη τύπου", + "type": { + "count": { + "label": "Αρίθμηση" + }, + "until": { + "conditions": "Μέχρι τις συνθήκες", + "label": "Μέχρι" + }, + "while": { + "conditions": "\"Μέχρι\" συνθήκες", + "label": "Μέχρι" + } + } + }, "scene": { "label": "Ενεργοποίηση σκηνής" }, @@ -770,6 +840,7 @@ "label": "Και" }, "device": { + "condition": "Προϋπόθεση", "extra_fields": { "above": "Πάνω από", "below": "Κάτω από", @@ -827,12 +898,20 @@ "load_error_not_editable": "Μόνο οι αυτοματισμοί στο automations.yaml είναι επεξεργάσιμοι.", "load_error_unknown": "Σφάλμα κατά τη φόρτωση αυτοματισμού ({err_no}).", "max": { + "parallel": "Μέγιστος αριθμός παράλληλων διαδρομών", "queued": "Μήκος ουράς" }, "modes": { + "description": "Η κατάσταση λειτουργίας ελέγχει τι συμβαίνει όταν ενεργοποιείται η αυτοματοποίηση ενώ οι ενέργειες εξακολουθούν να εκτελούνται από ένα προηγούμενο έναυσμα. Ελέγξτε το {documentation_link} για περισσότερες πληροφορίες.", "documentation": "τεκμηρίωση αυτοματισμού", - "restart": "Επανεκκίνηση" + "label": "Λειτουργία", + "parallel": "Παράλληλα", + "queued": "Στην ουρά", + "restart": "Επανεκκίνηση", + "single": "Μονό (προεπιλογή)" }, + "move_down": "Μετακίνηση προς τα κάτω", + "move_up": "Μετακίνηση προς τα επάνω", "save": "Αποθήκευση", "triggers": { "add": "Προσθήκη εναύσματος", @@ -851,7 +930,8 @@ "below": "Κάτω από", "for": "Διάρκεια" }, - "label": "Συσκευή" + "label": "Συσκευή", + "trigger": "Έναυσμα" }, "event": { "event_data": "Δεδομένα συμβάντος", @@ -1113,7 +1193,9 @@ "edit_requires_storage": "Ο επεξεργαστής απενεργοποιήθηκε επειδή οι ρυθμίσεις παραμέτρων αποθηκεύτηκαν στο αρχείο configuration.yaml.", "elevation": "Ανύψωση", "elevation_meters": "μέτρα", + "external_url": "Εξωτερική διεύθυνση URL", "imperial_example": "Φαρενάιτ, λίρες", + "internal_url": "Εσωτερική διεύθυνση URL", "latitude": "Γεωγραφικό πλάτος", "location_name": "Όνομα της εγκατάστασης του Home Assistant", "longitude": "Γεωγραφικό μήκος", @@ -1140,6 +1222,7 @@ "different_include": "Ίσως μέσω ενός τομέα, ενός glob ή μιας διαφορετικής προσθήκης.", "pick_attribute": "Επιλέξτε ένα χαρακτηριστικό για να το παρακάμψετε", "picker": { + "entity": "Οντότητα", "header": "Προσαρμογή", "introduction": "Αλλαγή ρυθμίσεων ανά οντότητα. Οι προσαρμοσμένες προσθήκες / επεξεργασίες θα τεθούν αμέσως σε ισχύ. Οι αφαιρεθείσες προσαρμογές θα ισχύσουν όταν ενημερωθεί η οντότητα." }, @@ -1176,14 +1259,18 @@ "integration": "Ενσωμάτωση", "manufacturer": "Κατασκευαστής", "model": "Μοντέλο", + "no_area": "Καμία περιοχή", "no_devices": "Δεν υπάρχουν συσκευές" }, "delete": "Διαγραφή", "description": "Διαχείριση συνδεδεμένων συσκευών", + "device_info": "Πληροφορίες συσκευής", "device_not_found": "Η συσκευή δε βρέθηκε.", "entities": { "add_entities_lovelace": "Προσθήκη στο Lovelace", + "disabled_entities": "+{count} {count, πληθυντικός,\n μία {απενεργοποιημένη οντότητα}\n άλλες {απενεργοποιημένες οντότητες}\n}", "entities": "Οντότητες", + "hide_disabled": "Η απόκρυψη είναι απενεργοποιημένη", "none": "Αυτή η συσκευή δεν έχει οντότητες" }, "name": "Όνομα", @@ -1224,11 +1311,13 @@ "status": "Κατάσταση" }, "introduction": "Ο Home Assistant διατηρεί μητρώο από κάθε μοναδική οντότητα που ανιχνεύει. Αυτές οι οντότητες έχουν το δικό τους μοναδικό αναγνωριστικό ID.", - "introduction2": "Χρησιμοποιήστε το μητρώο οντοτήτων για να παρακάμψετε το όνομα, να αλλάξετε το αναγνωριστικό οντότητας ή να καταργήσετε την καταχώρηση από το Home Assistant. Σημειώστε ότι η κατάργηση της καταχώρησης δεν θα καταργήσει την οντότητα. Για να το κάνετε αυτό, ακολουθήστε τον παρακάτω σύνδεσμο και αφαιρέστε την από τη σελίδα ενσωματώσεων.", + "introduction2": "Χρησιμοποιήστε το μητρώο οντοτήτων για να παρακάμψετε το όνομα, να αλλάξετε το αναγνωριστικό οντότητας ή να καταργήσετε την καταχώριση από το Home Assistant.", "remove_selected": { "button": "Αφαίρεση επιλεγμένων", + "confirm_text": "Θα πρέπει να τα αφαιρέσετε από το Lovelace config και τους αυτοματισμούς σας εάν περιέχουν αυτές τις οντότητες.", "confirm_title": "θέλετε να αφαιρέσετε {number} οντότητες;" }, + "search": "Οντότητες αναζήτησης", "selected": "Επιλέχθηκαν {number} ", "status": { "disabled": "Απενεργοποιημένη", @@ -1239,11 +1328,13 @@ }, "header": "Διαμόρφωση του Home Assistant", "helpers": { + "description": "Διαχειριστείτε στοιχεία που βοηθούν στη δημιουργία αυτοματισμών", "picker": { "headers": { "entity_id": "Αναγνωριστικό οντότητας", "name": "Ονομασία" - } + }, + "no_helpers": "Φαίνεται ότι δεν έχετε ακόμα βοηθούς!" }, "types": { "input_number": "Αριθμός", @@ -1252,12 +1343,17 @@ }, "info": { "built_using": "Κατασκευάστηκε με χρήση", + "caption": "Πληροφορίες", "custom_uis": "Προσαρμοσμένα περιβάλλοντα χρήστη:", + "description": "Δείτε πληροφορίες σχετικά με την εγκατάσταση του Home Assistant", "developed_by": "Αναπτύχθηκε από ένα μάτσο απίθανων ανθρώπων.", + "documentation": "Τεκμηρίωση", "frontend": "Τελική επιφάνεια εργασίας χρήστη", "frontend_version": "Έκδοση Frontend: {version} - {type}", "home_assistant_logo": "Λογότυπο του Home Assistant", "icons_by": "Εικόνες από", + "integrations": "Ενσωματώσεις", + "issues": "Ζητήματα", "license": "Δημοσιεύτηκε κάτω από την άδεια χρήσης Apache 2.0", "path_configuration": "Διαδρομή στo configuration.yaml: {path}", "server": "Διακομιστής", @@ -1266,7 +1362,9 @@ "title": "Πληροφορίες" }, "integration_panel_move": { - "link_integration_page": "Σελίδα ενσωματώσεων" + "link_integration_page": "Σελίδα ενσωματώσεων", + "missing_zha": "Λείπει ο πίνακας διαμόρφωσης ZHA; Μετακινήθηκε στην καταχώριση ZHA στο {integrations_page} .", + "missing_zwave": "Λείπει ο πίνακας διαμόρφωσης Z-Wave; Μετακινήθηκε στην καταχώριση Z-Wave στο {integrations_page} ." }, "integrations": { "caption": "Ενσωματώσεις", @@ -1285,7 +1383,8 @@ "no_devices": "Αυτή η ενοποίηση δεν έχει συσκευές.", "restart_confirm": "Επανεκκινήστε το Home Assistant για να ολοκληρώσετε την κατάργηση αυτής της ενοποίησης", "settings_button": "Επεξεργασία ρυθμίσεων για {integration}", - "system_options_button": "Επιλογές συστήματος για {integration}" + "system_options_button": "Επιλογές συστήματος για {integration}", + "unnamed_entry": "Ανώνυμη καταχώριση" }, "config_flow": { "aborted": "Ματαιώθηκε", @@ -1310,7 +1409,7 @@ "ignore": { "confirm_delete_ignore": "Αυτό θα κάνει την ενσωμάτωση να εμφανιστεί ξανά στις ενσωματώσεις που ανακαλύφθηκαν όταν ανακαλυφθεί. Αυτό μπορεί να απαιτήσει επανεκκίνηση ή να πάρει κάποιο χρόνο.", "confirm_delete_ignore_title": "Διακόψτε την παράβλεψη του {name};", - "confirm_ignore": "Είστε βέβαιοι ότι δε θέλετε να ρυθμίσετε αυτήν την ενσωμάτωση; Μπορείτε να αναιρέσετε αυτήν την επιλογή κάνοντας κλικ στο \"Εμφάνιση ενσωματώσεων που παραβλέφθηκαν\" στο μενού υπερχείλισης στην επάνω δεξιά γωνία.", + "confirm_ignore": "Είστε βέβαιοι ότι δεν θέλετε να ρυθμίσετε αυτήν την ενσωμάτωση; Μπορείτε να αναιρέσετε αυτό κάνοντας κλικ στην επιλογή \"Εμφάνιση αγνοημένων ενσωματώσεων\" στο μενού υπερχείλισης επάνω δεξιά.", "confirm_ignore_title": "Παράβλεψη της ανακάλυψη του {name} ;", "hide_ignored": "Απόκρυψη των ενσωματώσεων που παραβλέφθηκαν", "ignore": "Παράβλεψη", @@ -1327,7 +1426,9 @@ }, "introduction": "Εδώ είναι δυνατή η διαμόρφωση του Home Assistant και των εξαρτημάτων. Δεν είναι δυνατή η διαμόρφωση όλων από την διεπαφή χρήστη (UI) αλλά εργαζόμαστε πάνω σε αυτό.", "logs": { + "caption": "Αρχεία καταγραφής", "clear": "Καθαρισμός", + "description": "Δείτε τα αρχεία καταγραφής του Home Assistant", "details": "Λεπτομέρειες καταγραφής ({level})", "load_full_log": "Φόρτωση ολόκληρου του αρχείου καταγραφής του Home Assistant.", "loading_log": "Φόρτωση αρχείου καταγραφής σφαλμάτων…", @@ -1339,20 +1440,26 @@ }, "lovelace": { "dashboards": { + "cant_edit_default": "Δεν είναι δυνατή η επεξεργασία του τυπικού πίνακα ελέγχου Lovelace από τη διεπαφή χρήστη. Μπορείτε να το αποκρύψετε ορίζοντας έναν άλλο πίνακα ελέγχου ως προεπιλογή.", + "cant_edit_yaml": "Δεν είναι δυνατή η επεξεργασία πινάκων εργαλείων που ορίζονται στο YAML από το περιβάλλον εργασίας χρήστη. Αλλάξτε τα στο configuration.yaml.", "caption": "Επισκόπηση", "default_dashboard": "Αυτή είναι η προεπιλεγμένη επισκόπηση", "detail": { "icon": "Εικονίδιο", "title": "Τίτλος", - "title_required": "Απαιτείται τίτλος." + "title_required": "Απαιτείται τίτλος.", + "url_error_msg": "Η διεύθυνση URL πρέπει να περιέχει ένα - και δεν μπορεί να περιέχει κενά ή ειδικούς χαρακτήρες, εκτός από _ και -" }, "picker": { "headers": { "default": "Προεπιλογή" - } + }, + "open": "Άνοιγμα" } }, + "description": "Διαχειριστείτε τους πίνακες ελέγχου Lovelace", "resources": { + "cant_edit_yaml": "Χρησιμοποιείτε το Lovelace σε λειτουργία YAML, επομένως δεν μπορείτε να διαχειριστείτε τους πόρους σας μέσω του περιβάλλοντος εργασίας χρήστη. Διαχειριστείτε τους στο configuration.yaml.", "picker": { "no_resources": "Δεν υπάρχουν πόροι" } @@ -1372,6 +1479,18 @@ "title": "MQTT", "topic": "θέμα" }, + "ozw": { + "common": { + "node_id": "Αναγνωριστικό κόμβου", + "ozw_instance": "Παρουσία OpenZWave", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "Ο κόμβος απέτυχε", + "stage": "Στάδιο", + "zwave_info": "Πληροφορίες Z-Wave" + } + }, "person": { "add_person": "Προσθέστε Άτομο", "caption": "Άτομα", @@ -1453,14 +1572,20 @@ "delete_script": "Διαγραφή δέσμης ενεργειών", "header": "Δέσμη ενεργειών: {name}", "icon": "Εικονίδιο", + "id": "Αναγνωριστικό οντότητας", + "id_already_exists": "Αυτό το αναγνωριστικό υπάρχει ήδη", + "id_already_exists_save_error": "Δεν μπορείτε να αποθηκεύσετε αυτό το script επειδή το αναγνωριστικό δεν είναι μοναδικό, επιλέξτε άλλο αναγνωριστικό ή αφήστε το κενό για αυτόματη δημιουργία ενός.", "introduction": "Χρησιμοποιήστε δέσμες ενεργειών για να εκτελέσετε μια ακολουθία ενεργειών.", "link_available_actions": "Μάθετε περισσότερα σχετικά με τις διαθέσιμες ενέργειες.", "load_error_not_editable": "Μόνο οι δέσμες ενεργειών που βρίσκονται μέσα στο scripts.yaml είναι επεξεργάσιμες", "max": { + "parallel": "Μέγιστος αριθμός παράλληλων διαδρομών", "queued": "Μήκος ουράς" }, "modes": { + "description": "Η λειτουργία ελέγχει τι συμβαίνει όταν γίνεται κλήση σεναρίου, ενώ εξακολουθεί να εκτελείται από μία ή περισσότερες προηγούμενες προσκλήσεις. Ελέγξτε το {documentation_link} για περισσότερες πληροφορίες.", "documentation": "τεκμηρίωση δέσμης ενεργειών", + "label": "Λειτουργία", "parallel": "Παράλληλα", "queued": "Στην ουρά", "restart": "Επανεκκίνηση", @@ -1479,6 +1604,7 @@ "introduction": "Ο επεξεργαστής δέσμης ενεργειών σας επιτρέπει να δημιουργείτε και να επεξεργάζεστε σκηνές. Παρακαλώ ακολουθήστε τον παρακάτω σύνδεσμο για να διαβάσετε τις οδηγίες για να βεβαιωθείτε ότι έχετε διαμορφώσει σωστά το Home Assistant.", "learn_more": "Μάθετε περισσότερα σχετικά με τα σενάρια", "no_scripts": "Δεν μπορέσαμε να βρούμε δέσμες ενεργειών με δυνατότητα επεξεργασίας", + "show_info": "Εμφάνιση πληροφοριών σχετικά με τη δέσμη ενεργειών", "trigger_script": "Δέσμη ενεργειών εναύσματος" } }, @@ -1491,6 +1617,11 @@ "core": "Επαναφόρτωση τοποθεσίας και προσαρμογών", "group": "Επαναφόρτωση ομάδων", "heading": "Επαναφόρτωση παραμετροποίησης YAML ", + "input_boolean": "Επαναφόρτωση δυαδικών μεταβλητών εισόδου", + "input_datetime": "Επαναφόρτωση ημερομηνίας εισαγωγής", + "input_number": "Επαναφόρτωση αριθμών εισόδου", + "input_select": "Επαναφόρτωση δέσμης εντολών", + "input_text": "Επαναφόρτωση κειμένων εισόδου", "introduction": "Ορισμένα τμήματα του Home Assistant μπορούν να επαναφορτωθούν χωρίς να απαιτείται επανεκκίνηση. Πατώντας \"επαναφόρτωση\" θα ξεφορτωθεί η τρέχουσα παραμετροποίηση YAML και θα φορτωθεί η νέα.", "scene": "Επαναφόρτωση σκηνών", "script": "Επαναφόρτωση δέσμης εντολών" @@ -1536,6 +1667,7 @@ "name": "Ονομασία", "owner": "Ιδιοκτήτης", "system_generated": "Δημιουργήθηκε από το σύστημα", + "system_generated_users_not_editable": "Δεν είναι δυνατή η ενημέρωση των χρηστών που δημιουργούνται από το σύστημα.", "system_generated_users_not_removable": "Δεν είναι δυνατή η διαγραφή χρηστών που δημιουργήθηκαν από το σύστημα", "unnamed_user": "Χρήστης χωρίς όνομα", "update_user": "Ενημέρωση" @@ -1546,13 +1678,16 @@ "name": "Ονομασία", "system": "Σύστημα" } - } + }, + "users_privileges_note": "Η ομάδα χρηστών είναι ένα έργο σε εξέλιξη. Ο χρήστης δεν θα μπορεί να διαχειριστεί την παρουσία μέσω της διεπαφής χρήστη. Εξακολουθούμε να ελέγχουμε όλα τα τελικά σημεία API διαχείρισης για να διασφαλίσουμε ότι περιορίζουν σωστά την πρόσβαση στους διαχειριστές." }, "zha": { "add_device_page": { "discovered_text": "Οι συσκευές θα εμφανιστούν εδώ μόλις ανακαλυφθούν.", "discovery_text": "Οι ανακαλυφθείσες συσκευές θα εμφανιστούν εδώ. Ακολουθήστε τις οδηγίες για τις συσκευές σας και τοποθετήστε τις συσκευές στη λειτουργία αντιστοίχισης.", "header": "Zigbee Home Automation - Προσθήκη Συσκευών", + "no_devices_found": "Δεν βρέθηκαν συσκευές, βεβαιωθείτε ότι βρίσκονται σε λειτουργία ζευγαρώματος και κρατήστε τις ξύπνιες ενώ η ανακάλυψη εκτελείται.", + "pairing_mode": "Βεβαιωθείτε ότι οι συσκευές σας είναι σε λειτουργία σύζευξης. Ελέγξτε τις οδηγίες της συσκευής σας για το πώς να το κάνετε αυτό.", "search_again": "Αναζήτηση ξανά", "spinner": "Αναζήτηση συσκευών ZHA Zigbee…" }, @@ -1602,7 +1737,7 @@ "create_group": "Zigbee Home Automation - Δημιουργία ομάδας", "create_group_details": "Καταχωρείστε τις απαραίτητες πληροφορίες για να δημιουργήσετε μια νέα ομάδα Zigbee", "creating_group": "Δημιουργία ομάδας", - "description": "Δημιούργησε και τροποποίησε ομάδες Zigbee", + "description": "Διαχείριση ομάδων Zigbee", "group_details": "Εδώ βρίσκονται όλες οι πληροφορίες για την επιλεγμένη ομάδα", "group_id": "Αναγνωριστικό ομάδας", "group_info": "Πληροφορίες ομάδας", @@ -1638,7 +1773,11 @@ "title": "Zigbee Home Automation" }, "zone": { - "edit_home_zone": "Η τοποθεσία του σπιτιού σας μπορεί να αλλαχτεί από τις γενικές ρυθμίσεις." + "description": "Διαχειριστείτε τις ζώνες στις οποίες θέλετε να παρακολουθείτε άτομα", + "detail": { + "passive_note": "Οι παθητικές ζώνες είναι κρυμμένες στο μπροστινό μέρος και δεν χρησιμοποιούνται ως θέση για ιχνηλάτες συσκευών. Αυτό είναι χρήσιμο εάν θέλετε ακριβώς να το χρησιμοποιήσετε για τους αυτοματισμούς." + }, + "edit_home_zone": "Δεν είναι δυνατή η επεξεργασία της ακτίνας της ζώνης Home από το Frontend. Σύρετε το δείκτη στο χάρτη για να μετακινήσετε τη ζώνη της αρχικής σελίδας." }, "zwave": { "button": "Διαμόρφωση", @@ -1674,21 +1813,45 @@ "set_wakeup": "Ορισμός διαστήματος αφύπνισης", "true": "Αληθής" }, + "node_management": { + "add_to_group": "Προσθήκη σε ομάδα", + "group": "Ομάδα", + "header": "Διαχείριση κόμβων Z-Wave", + "max_associations": "Μέγιστες ενώσεις:", + "node_group_associations": "Κόμβοι συσχετίσεων ομάδων", + "node_to_control": "Κόμβος προς έλεγχο", + "nodes_in_group": "Άλλοι κόμβοι σε αυτήν την ομάδα:", + "protection": "Προστασία", + "remove_broadcast": "Κατάργηση εκπομπής", + "remove_from_group": "Κατάργηση από ομάδα", + "set_protection": "Ορισμός προστασίας" + }, "ozw_log": { "header": "Αρχείο καταγραφής OZW", - "introduction": "Δείτε το αρχείο καταγραφής. 0 είναι το ελάχιστο (φορτώνει ολόκληρο το αρχείο καταγραφής) και 1000 είναι το μέγιστο. Η φόρτωση θα εμφανίσει ένα στατικό αρχείο καταγραφής και η ουρά θα ενημερωθεί αυτόματα με τον τελευταίο καθορισμένο αριθμό γραμμών του αρχείου καταγραφής." + "introduction": "Δείτε το αρχείο καταγραφής. 0 είναι το ελάχιστο (φορτώνει ολόκληρο το αρχείο καταγραφής) και 1000 είναι το μέγιστο. Η φόρτωση θα εμφανίσει ένα στατικό αρχείο καταγραφής και η ουρά θα ενημερωθεί αυτόματα με τον τελευταίο καθορισμένο αριθμό γραμμών του αρχείου καταγραφής.", + "last_log_lines": "Αριθμός τελευταίων γραμμών καταγραφής", + "load": "Φόρτωση", + "tail": "Ουρά" }, "services": { "add_node": "Προσθήκη κόμβου", "add_node_secure": "Ασφαλής προσθήκη κόμβου", "cancel_command": "Ακύρωση εντολής", "heal_network": "Θεραπεία δικτύου", + "heal_node": "Θεραπεία κόμβου", + "node_info": "Πληροφορίες κόμβου", + "print_node": "Εκτύπωση κόμβου", + "refresh_entity": "Ανανέωση οντότητας", + "refresh_node": "Ανανέωση κόμβου", + "remove_failed_node": "Κατάργηση αποτυχημένου κόμβου", "remove_node": "Κατάργηση κόμβου", + "replace_failed_node": "Αντικατάσταση αποτυχημένου κόμβου", "save_config": "Αποθήκευση Παραμετροποίησης", "soft_reset": "Επαναφορά μέσω λογισμικού", "start_network": "Έναρξη δικτύου", "stop_network": "Διακοπή δικτύου", - "test_network": "Δοκιμή δικτύου" + "test_network": "Δοκιμή δικτύου", + "test_node": "Δοκιμή κόμβου" }, "values": { "header": "Τιμές κόμβου" @@ -1786,7 +1949,9 @@ }, "lovelace": { "add_entities": { - "saving_failed": "Η αποθήκευση της παραμετροποίησης του Lovelace απέτυχε" + "generated_unsupported": "Μπορείτε να χρησιμοποιήσετε αυτήν τη λειτουργία μόνο όταν έχετε πάρει τον έλεγχο του Lovelace UI.", + "saving_failed": "Η αποθήκευση της παραμετροποίησης του Lovelace απέτυχε", + "yaml_unsupported": "Δεν μπορείτε να χρησιμοποιήσετε αυτήν τη λειτουργία όταν χρησιμοποιείτε το Lovelace UI σε λειτουργία YAML." }, "cards": { "confirm_delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν την κάρτα;", @@ -1876,6 +2041,7 @@ "no_theme": "Χωρίς θέμα", "refresh_interval": "Χρονικό διάστημα ανανέωσης", "search": "Αναζήτηση", + "secondary_info_attribute": "Χαρακτηριστικό δευτερευουσών πληροφοριών", "show_icon": "Εμφάνιση εικονιδίου;", "show_name": "Εμφάνιση ονόματος;", "show_state": "Εμφάνιση κατάστασης;", @@ -1897,6 +2063,7 @@ "name": "Οριζόντια διάταξη" }, "humidifier": { + "description": "Η κάρτα υγραντήρα δίνει τον έλεγχο της οντότητας υγραντήρα σας. Σας επιτρέπει να αλλάξετε την υγρασία και τον τρόπο της οντότητας.", "name": "Υγραντήρας" }, "iframe": { @@ -1909,6 +2076,7 @@ "dark_mode": "Σκοτεινή λειτουργία;", "default_zoom": "Προεπιλεγμένο ζουμ", "geo_location_sources": "Πηγές γεωγραφικής θέσης", + "hours_to_show": "Ώρες για εμφάνιση", "name": "Χάρτης", "source": "Πηγή" }, @@ -1949,7 +2117,8 @@ "name": "Κάθετη διάταξη" }, "weather-forecast": { - "name": "Πρόγνωση καιρού" + "name": "Πρόγνωση καιρού", + "show_forecast": "Πρόγνωση καιρού" } }, "cardpicker": { @@ -1958,6 +2127,7 @@ }, "edit_card": { "add": "Προσθήκη κάρτας", + "confirm_cancel": "Είστε βέβαιοι ότι θέλετε να ακυρώσετε;", "delete": "Διαγραφή", "duplicate": "Διπλότυπη κάρτα", "edit": "Επεξεργασία", @@ -1968,7 +2138,9 @@ "pick_card_view_title": "Ποια κάρτα θέλετε να προσθέσετε στην προβολή {name} ;", "show_code_editor": "Εμφάνιση επεξεργαστή κώδικα", "show_visual_editor": "Εμφάνιση οπτικού προγράμματος επεξεργασίας", - "toggle_editor": "Εναλλαγή κειμενογράφου" + "toggle_editor": "Εναλλαγή κειμενογράφου", + "typed_header": "{τύπος} Διαμόρφωση κάρτας", + "unsaved_changes": "Έχετε μη αποθηκευμένες αλλαγές" }, "edit_lovelace": { "edit_title": "Επεξεργασία τίτλου", @@ -1997,13 +2169,19 @@ "para_migrate": "Ο Home Assistant μπορεί να προσθέσει αυτόματα όλα τα αναγνωριστικά από τις κάρτες και τις προβολές σας πατώντας το πλήκτρο 'Ρυθμίσεις μετεγκατάστασης'.", "para_no_id": "Αυτό το στοιχείο δεν έχει αναγνωριστικό. Προσθέστε ένα αναγνωριστικό σε αυτό το στοιχείο στο 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Επιλέξτε μια προβολή για να μετακινήσετε την κάρτα" + }, "raw_editor": { + "confirm_remove_config_text": "Θα δημιουργήσουμε αυτόματα τις προβολές του Lovelace UI με τις περιοχές και τις συσκευές σας, εάν καταργήσετε τη διαμόρφωση του Lovelace UI.", + "confirm_remove_config_title": "Είστε βέβαιοι ότι θέλετε να καταργήσετε τη διαμόρφωση διεπαφής χρήστη Lovelace; Θα δημιουργήσουμε αυτόματα τις προβολές διεπαφής χρήστη Lovelace με τις περιοχές και τις συσκευές σας.", "confirm_unsaved_changes": "Έχετε μη-αποθηκευμένες αλλαγές, είστε βέβαιοι ότι θέλετε να βγείτε;", "confirm_unsaved_comments": "Η παραμετροποίηση σας περιέχει σχόλιο(α), αυτά δεν θα αποθηκευτούν. Θέλετε να συνεχίσετε;", - "error_invalid_config": "Το αρχείο config δεν είναι έγκυρο: {error}", + "error_invalid_config": "Η διαμόρφωσή σας δεν είναι έγκυρη: {error}", "error_parse_yaml": "Δεν είναι δυνατή η ανάλυση του YAML: {error}", + "error_remove": "Δεν είναι δυνατή η κατάργηση της διαμόρφωσης: {error}", "error_save_yaml": "Δεν είναι δυνατή η αποθήκευση του YAML: {error}", - "header": "Επεξεργαστείτε το Config", + "header": "Επεξεργασία διαμόρφωσης", "save": "Αποθήκευση", "saved": "Αποθηκεύτηκε", "unsaved_changes": "Μη αποθηκευμένες αλλαγές" @@ -2014,9 +2192,15 @@ "header": "Πάρτε τον έλεγχο του περιβάλλοντος χρήστη στο Lovelace", "para": "Από προεπιλογή, το Home Assistant θα διατηρήσει το περιβάλλον χρήστη που έχετε ενημερώνοντας το όταν θα γίνονται διαθέσιμες νέες οντότητες ή στοιχεία Lovelace. Αν πάρετε τον έλεγχο, δεν θα πραγματοποιούμε πλέον αλλαγές για εσάς.", "para_sure": "Είστε βέβαιος ότι θέλετε να πάρετε τον έλεγχο του περιβάλλοντος χρήστη;", - "save": "Πάρτε τον έλεγχο" + "save": "Πάρτε τον έλεγχο", + "yaml_mode": "Χρησιμοποιείτε τη λειτουργία YAML για αυτόν τον πίνακα εργαλείων, πράγμα που σημαίνει ότι δεν μπορείτε να αλλάξετε τη διαμόρφωση Lovelace από το περιβάλλον εργασίας χρήστη. Εάν θέλετε να διαχειριστείτε αυτόν τον πίνακα εργαλείων από το περιβάλλον εργασίας χρήστη, καταργήστε το 'mode: yaml' από τη διαμόρφωση Lovelace στο 'configuration.yaml.'." + }, + "select_view": { + "dashboard_label": "Επισκόπηση", + "header": "Επιλέξτε μια προβολή" }, "suggest_card": { + "add": "Προσθήκη στο Lovelace UI", "create_own": "Επιλέξτε άλλη κάρτα" }, "view": { @@ -2043,15 +2227,20 @@ "entity": "Οντότητα", "entity_id": "Αναγνωριστικό οντότητας", "last_changed": "Τελευταία αλλαγή", + "no_data": "Δεν βρέθηκαν αχρησιμοποίητες οντότητες", + "search": "Οντότητες αναζήτησης", "select_to_add": "Επιλέξτε τις οντότητες που θέλετε να προσθέσετε σε μια κάρτα και, στη συνέχεια, κάντε κλικ στο κουμπί Προσθήκη κάρτας.", "title": "Αχρησιμοποίητες οντότητες" }, "views": { - "confirm_delete": "Θέλετε να διαγράψετε αυτήν την προβολή;" + "confirm_delete": "Θέλετε να διαγράψετε αυτήν την προβολή;", + "confirm_delete_existing_cards_text": "Είστε βέβαιοι ότι θέλετε να διαγράψετε την προβολή '' {name} ''; Η προβολή περιέχει {number} κάρτες που θα διαγραφούν. Αυτή η πράξη δε μπορεί να αναιρεθεί.", + "confirm_delete_text": "Είστε βέβαιοι ότι θέλετε να διαγράψετε την προβολή '' {name} '';" }, "warning": { "entity_non_numeric": "Η οντότητα δεν είναι αριθμητική: {entity}", - "entity_not_found": "Η οντότητα δεν είναι διαθέσιμη: {entity}" + "entity_not_found": "Η οντότητα δεν είναι διαθέσιμη: {entity}", + "starting": "Το Home Assistant ξεκινά, ενδέχεται να μην είναι ακόμη διαθέσιμα όλα" } }, "mailbox": { @@ -2064,6 +2253,8 @@ "abort_intro": "Σύνδεση ματαιώθηκε", "authorizing_client": "Πρόκειται να δώσετε στο {clientId} πρόσβαση στο Home Assistant.", "form": { + "error": "Σφάλμα: {error}", + "next": "Επόμενο", "providers": { "command_line": { "abort": { @@ -2150,6 +2341,7 @@ } } }, + "start_over": "Ξεκινήστε από την αρχή", "unknown_error": "Κάτι πήγε στραβά", "working": "Παρακαλώ περιμένετε" }, @@ -2311,13 +2503,22 @@ "token_title": "Ανανέωση διακριτικού για το {clientId}" }, "suspend": { + "description": "Θα πρέπει να κλείσουμε τη σύνδεση με το διακομιστή μετά την απόκρυψη για 5 λεπτά;", "header": "Αυτόματο κλείσιμο σύνδεσης" }, "themes": { + "accent_color": "Χρώμα έμφασης", + "dark_mode": { + "auto": "Αυτόματο", + "dark": "Σκούρο", + "light": "Φωτεινό" + }, "dropdown_label": "Θέμα", "error_no_theme": "Δεν υπάρχουν διαθέσιμα θέματα.", "header": "Θέμα", - "link_promo": "Μάθετε σχετικά με τα θέματα" + "link_promo": "Μάθετε σχετικά με τα θέματα", + "primary_color": "Πρωτεύον χρώμα", + "reset": "Επαναφορά" }, "vibrate": { "description": "Ενεργοποιήστε ή απενεργοποιήστε τις δονήσεις σε αυτήν τη συσκευή κατά τον έλεγχο συσκευών.", diff --git a/translations/frontend/en.json b/translations/frontend/en.json index e43714330a..7abcf52ea9 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -1656,6 +1656,37 @@ "node_failed": "Node Failed", "stage": "Stage", "zwave_info": "Z-Wave Info" + }, + "node_query_stages": { + "associations": "Refreshing association groups and memberships", + "cacheload": "Loading information from the OpenZWave cache file. Battery nodes will stay at this stage until the node wakes up.", + "complete": "Interview process is complete", + "configuration": "Obtaining configuration values from the node", + "dynamic": "Obtaining frequently changing values from the node", + "instances": "Obtaining details about what instances or channels a device supports", + "manufacturerspecific1": "Obtaining manufacturer and product ID codes from the node", + "manufacturerspecific2": "Obtaining additional manufacturer and product ID codes from the node", + "neighbors": "Obtaining a list of the node's neighbors", + "nodeinfo": "Obtaining supported command classes from the node", + "nodeplusinfo": "Obtaining Z-Wave+ information from the node", + "probe": "Checking if the node is awake/alive", + "protocolinfo": "Obtaining basic Z-Wave capabilities of this node from the controller", + "session": "Obtaining infrequently changing values from the node", + "static": "Obtaining static values from the device", + "versions": "Obtaining information about firmware and command class versions", + "wakeup": "Setting up support for wakeup queues and messages" + }, + "refresh_node": { + "battery_note": "If the node is battery powered, be sure to wake it before proceeding", + "complete": "Node Refresh Complete", + "description": "This will tell OpenZWave to re-interview a node and update the node's command classes, capabilities, and values.", + "node_status": "Node Status", + "refreshing_description": "Refreshing node information...", + "start_refresh_button": "Start Refresh", + "step": "Step", + "title": "Refresh Node Information", + "wakeup_header": "Wakeup Instructions for", + "wakeup_instructions_source": "Wakeup instructions are sourced from the OpenZWave community device database." } }, "person": { diff --git a/translations/frontend/fy.json b/translations/frontend/fy.json index 9d3024376c..119c6b7034 100644 --- a/translations/frontend/fy.json +++ b/translations/frontend/fy.json @@ -9,11 +9,15 @@ "state_attributes": { "climate": { "fan_mode": { - "off": "Út" + "off": "Út", + "on": "Oan" } } }, "state_badge": { + "default": { + "unknown": "Ûnbek." + }, "person": { "home": "Thús" } @@ -22,6 +26,10 @@ "alarm_control_panel": { "triggered": "Aktivearre" }, + "automation": { + "off": "Út", + "on": "Oan" + }, "binary_sensor": { "cold": { "on": "Kâld" @@ -30,6 +38,7 @@ "on": "Ferbûn" }, "default": { + "off": "Út", "on": "Oan" }, "door": { @@ -71,7 +80,9 @@ "heat": "Ferwaarmje" }, "cover": { - "open": "Iepen" + "closing": "Slút", + "open": "Iepen", + "opening": "Iepent" }, "default": { "off": "Út", @@ -87,6 +98,8 @@ "group": { "home": "Thús", "locked": "Beskoattele", + "off": "Út", + "on": "Oan", "open": "Iepen", "stopped": "Stoppe" }, diff --git a/translations/frontend/he.json b/translations/frontend/he.json index e6ae133790..933e5bb3c8 100644 --- a/translations/frontend/he.json +++ b/translations/frontend/he.json @@ -162,7 +162,7 @@ "on": "פתוח" }, "presence": { - "off": "לא נוכח", + "off": "לא נמצא", "on": "בבית" }, "problem": { @@ -306,7 +306,7 @@ "docked": "בעגינה", "error": "שגיאה", "idle": "ממתין", - "off": "מכובה", + "off": "כבוי", "on": "מופעל", "paused": "מושהה", "returning": "חזור לעגינה" @@ -344,7 +344,7 @@ "ui": { "auth_store": { "ask": "האם ברצונך לשמור את ההתחברות הזו?", - "confirm": "שמור התחברות", + "confirm": "כן", "decline": "לא תודה" }, "card": { @@ -748,7 +748,7 @@ "unknown": "לא ידוע", "zha_device_card": { "area_picker_label": "אזור", - "device_name_placeholder": "שם פרטי", + "device_name_placeholder": "שנה שם התקן", "update_name_button": "עדכן שם" } } diff --git a/translations/frontend/it.json b/translations/frontend/it.json index d22f43449c..fc6980fc46 100644 --- a/translations/frontend/it.json +++ b/translations/frontend/it.json @@ -836,7 +836,7 @@ "choose": { "add_option": "Aggiungi opzione", "conditions": "Condizioni", - "default": "Azione predefinita", + "default": "Azioni predefinite", "label": "Scegli", "option": "Opzione {number}", "remove_option": "Rimuovi opzione", @@ -2050,7 +2050,7 @@ "add_node": "Aggiungi Nodo", "add_node_secure": "Aggiungi nodo sicuro", "cancel_command": "Annulla Comando", - "heal_network": "Testa la rete", + "heal_network": "Risana la rete", "heal_node": "Resuscita Nodo", "node_info": "Informazioni sul Nodo", "print_node": "Stampa Nodo", diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 521c567b22..0a74b9f1ea 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -798,7 +798,7 @@ "confirmation_text": "이 영역에 속한 모든 장치가 할당 해제됩니다.", "confirmation_title": "이 영역을 삭제하시겠습니까?" }, - "description": "영역을 만들고 편집합니다", + "description": "집의 영역을 관리합니다", "editor": { "area_id": "영역 ID", "create": "만들기", @@ -820,7 +820,7 @@ }, "automation": { "caption": "자동화", - "description": "자동화를 만들고 편집합니다", + "description": "자동화를 관리합니다", "editor": { "actions": { "add": "동작 추가", @@ -833,6 +833,15 @@ "name": "동작", "type_select": "동작 유형", "type": { + "choose": { + "add_option": "옵션 추가", + "conditions": "조건", + "default": "기본 동작", + "label": "선택", + "option": "옵션 {number}", + "remove_option": "옵션 제거", + "sequence": "동작" + }, "condition": { "label": "조건" }, @@ -852,6 +861,24 @@ "label": "이벤트 발생", "service_data": "서비스 데이터" }, + "repeat": { + "label": "반복", + "sequence": "동작", + "type_select": "반복 유형", + "type": { + "count": { + "label": "횟수" + }, + "until": { + "conditions": "~일 때 까지 (조건)", + "label": "~일 때 까지" + }, + "while": { + "conditions": "~인 동안 (조건)", + "label": "~인 동안" + } + } + }, "scene": { "label": "씬 활성화" }, @@ -1341,7 +1368,7 @@ }, "entities": { "caption": "구성요소", - "description": "등록된 구성요소를 편집합니다", + "description": "등록된 구성요소를 관리합니다", "picker": { "disable_selected": { "button": "선택된 구성요소 비활성화", @@ -1393,7 +1420,7 @@ "header": "Home Assistant 설정", "helpers": { "caption": "도우미", - "description": "자동화 구축에 도움이 되는 요소입니다", + "description": "자동화 구축에 도움이 되는 요소를 관리합니다", "dialog": { "add_helper": "도우미 추가", "add_platform": "{platform} 추가", @@ -1486,7 +1513,7 @@ }, "configure": "설정하기", "configured": "설정된 통합 구성요소", - "description": "통합 구성요소를 관리하고 설정합니다", + "description": "통합 구성요소를 관리합니다", "details": "통합 구성요소 상세정보", "discovered": "발견된 구성요소", "home_assistant_website": "Home Assistant 웹 사이트", @@ -1514,7 +1541,7 @@ "rename_input_label": "구성 항목의 이름", "search": "통합 구성요소 검색" }, - "introduction": "여기에서 구성요소와 Home Assistant 를 설정할 수 있습니다. 아직 여기서 모두 설정할 수는 없지만, 모든 내용을 설정할 수 있도록 작업 중입니다.", + "introduction": "이 뷰에서 구성요소와 Home Assistant 를 설정할 수 있습니다. 아직 여기서 모두 설정할 수는 없지만, 모든 내용을 설정할 수 있도록 작업 중입니다.", "logs": { "caption": "로그", "clear": "지우기", @@ -1570,7 +1597,7 @@ "open": "열기" } }, - "description": "Lovelace 대시보드를 구성합니다", + "description": "Lovelace 대시보드를 관리합니다", "resources": { "cant_edit_yaml": "YAML 모드에서 Lovelace 를 사용하고 있으므로 UI 를 통해 리소스를 관리할 수 없습니다. configuration.yaml 에서 관리해주세요.", "caption": "리소스", @@ -1619,6 +1646,18 @@ "title": "MQTT", "topic": "토픽" }, + "ozw": { + "common": { + "node_id": "노드 ID", + "ozw_instance": "OpenZWave 인스턴스", + "zwave": "Z-Wave" + }, + "device_info": { + "node_failed": "노드 실패", + "stage": "단계", + "zwave_info": "Z-Wave 정보" + } + }, "person": { "add_person": "구성원 추가하기", "caption": "구성원", @@ -1648,7 +1687,7 @@ "scene": { "activated": "{name} 씬이 활성화 됨.", "caption": "씬", - "description": "씬을 만들고 편집합니다", + "description": "씬을 관리합니다", "editor": { "default_name": "새로운 씬", "devices": { @@ -1692,7 +1731,7 @@ }, "script": { "caption": "스크립트", - "description": "스크립트를 만들고 편집합니다", + "description": "스크립트를 관리합니다", "editor": { "alias": "이름", "default_name": "새로운 스크립트", @@ -1879,7 +1918,7 @@ "create_group": "Zigbee Home Automation - 그룹 만들기", "create_group_details": "새로운 Zigbee 그룹을 생성하기 위해 필요한 세부 사항을 입력해주세요", "creating_group": "그룹 생성", - "description": "Zigbee 그룹을 생성하거나 수정합니다", + "description": "Zigbee 그룹을 관리합니다", "group_details": "선택된 Zigbee 그룹의 모든 세부 정보는 다음과 같습니다.", "group_id": "그룹 ID", "group_info": "그룹 정보", @@ -2387,6 +2426,9 @@ "para_migrate": "Home Assistant 는 '구성 마이그레이션' 버튼을 눌러 자동으로 모든 카드와 뷰에 ID를 추가할 수 있습니다.", "para_no_id": "이 요소에는 ID가 없습니다. 'ui-lovelace.yaml' 에 요소의 ID를 추가해주세요." }, + "move_card": { + "header": "카드를 이동할 뷰를 선택해주세요" + }, "raw_editor": { "confirm_remove_config_text": "Lovelace UI 구성을 제거하면, 영역 및 기기와 함께 Lovelace UI 뷰가 자동으로 생성됩니다.", "confirm_remove_config_title": "Lovelace UI 구성을 제거하시겠습니까? 영역 및 기기와 함께 Lovelace UI 뷰를 자동으로 생성해드립니다.", @@ -2414,6 +2456,10 @@ "yaml_control": "YAML 모드로 제어하려면 대시보드의 구성에서 지정한 이름의 YAML 파일을 만들거나 기본 제공된 'ui-lovelace.yaml' 을 사용해주세요.", "yaml_mode": "이 대시보드는 YAML 모드를 사용 중이므로 UI 에서 Lovelace 구성을 변경할 수 없습니다. Lovelace 를 UI 에서 변경하려면 'configuration.yaml' 의 Lovelace 구성에서 'mode:yaml' 을 제거해주세요." }, + "select_view": { + "dashboard_label": "대시보드", + "header": "뷰 선택" + }, "suggest_card": { "add": "Lovelace UI 에 추가", "create_own": "다른 카드 선택", @@ -2429,7 +2475,7 @@ }, "menu": { "close": "닫기", - "configure_ui": "UI 구성", + "configure_ui": "대시보드 편집", "exit_edit_mode": "UI 편집 모드 종료", "help": "도움말", "refresh": "새로고침", @@ -2731,10 +2777,18 @@ "header": "자동 연결 종료" }, "themes": { + "accent_color": "강조 색상", + "dark_mode": { + "auto": "자동", + "dark": "어둡게", + "light": "밝게" + }, "dropdown_label": "테마", "error_no_theme": "사용할 수 있는 테마가 없습니다.", "header": "테마", - "link_promo": "테마에 대해 더 알아보기" + "link_promo": "테마에 대해 더 알아보기", + "primary_color": "주 색상", + "reset": "초기화" }, "vibrate": { "description": "기기를 제어할 때 이 기기에서 진동을 활성화 또는 비활성화합니다.", diff --git a/translations/frontend/nn.json b/translations/frontend/nn.json index c865e0c752..56b1204383 100644 --- a/translations/frontend/nn.json +++ b/translations/frontend/nn.json @@ -346,7 +346,7 @@ }, "automation": { "last_triggered": "Sist utløyst", - "trigger": "Utløysar" + "trigger": "Utfør" }, "camera": { "not_available": "Bilete ikkje tilgjengeleg" @@ -499,7 +499,8 @@ }, "entity": { "entity-picker": { - "entity": "Eining" + "entity": "Eining", + "show_entities": "Vis oppføringar" } }, "history_charts": { @@ -583,6 +584,7 @@ } }, "mqtt_device_debug_info": { + "entities": "Oppføringar", "no_entities": "Ingen oppføringar", "no_triggers": "Ingen utløysarar", "payload_display": "Nyttelastvisning", @@ -704,7 +706,7 @@ "label": "Gjenta" }, "service": { - "label": "Hent teneste", + "label": "Utfør tenestekall", "service_data": "Tenestedata" }, "wait_template": { @@ -802,7 +804,7 @@ "below": "Under" }, "label": "Oppføring", - "trigger": "Utløysar " + "trigger": "Utfør" }, "event": { "event_data": "TIlstandsdata", @@ -955,6 +957,7 @@ }, "cant_edit": "Du kan berre redigere element som er laga i brukargrensesnittet.", "caption": "Einingar", + "confirm_rename_entity_ids": "Vil du også endre ID-ane til oppføringane dine?", "data_table": { "area": "Område", "battery": "Batteri", @@ -965,7 +968,8 @@ "description": "Administrer tilkopla einingar", "device_info": "Einingsinfo ", "entities": { - "disabled_entities": "+{count} {count, plural,\n one {disabled entity}\n other {disabled entities}\n}", + "disabled_entities": "+{count} {count, plural,\n one {deaktivert oppføring}\n other {deaktiverte oppføringar}\n}", + "entities": "Oppføringar", "hide_disabled": "Skjul deaktiverte" }, "name": "Namn", @@ -989,8 +993,14 @@ "description": "Oversikt over alle kjende oppføringar.", "picker": { "header": "Oppføringsregisteret", + "headers": { + "entity_id": "Oppførings-ID", + "integration": "Integrasjon", + "name": "Namn" + }, "introduction": "Home Assistant har eit register over alle oppføringane den nokon gang har sett som kan unikt identifiserast. Kvar av desse oppføringane har ein eigen oppføringsidentifikasjon som er reservert for akkurat denne oppføringa.", - "introduction2": "Bruk oppføringsregisteret til å skrive over namn, endre oppføringsidentifikasjonane eller fjerne oppføringar frå Home Assistant. Merk deg at å fjerne oppføringa i oppføringregisteret ikkje fjernar sjølve oppføringa. For å gjere dette, gå vidare inn på linken under og fjern oppføringa i integrasjonssida." + "introduction2": "Bruk oppføringsregisteret til å skrive over namn, endre oppføringsidentifikasjonane eller fjerne oppføringar frå Home Assistant. Merk deg at å fjerne oppføringa i oppføringregisteret ikkje fjernar sjølve oppføringa. For å gjere dette, gå vidare inn på linken under og fjern oppføringa i integrasjonssida.", + "search": "Søk i oppføringar" } }, "filtering": { @@ -1012,8 +1022,8 @@ "delete": "Slett", "delete_confirm": "Er du sikker på at du vil slette denne integrasjonen?", "device_unavailable": "Eininga utilgjengelig", - "devices": "{count} {count, plural,\n one {device}\n other {devices}\n}", - "entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}", + "devices": "{count} {count, plural,\n one {eining}\n other {einingar}\n}", + "entities": "{count} {count, plural,\n one {oppføring}\n other {oppføringar}\n}", "entity_unavailable": "Oppføringa utilgjengelig", "firmware": "Firmware: {version}", "hub": "Tilkopla via", @@ -1070,6 +1080,11 @@ }, "scene": { "editor": { + "entities": { + "add": "Legg til ei oppføring", + "delete": "Slett oppføring", + "header": "Oppføringar" + }, "icon": "Ikon" }, "picker": { @@ -1294,6 +1309,7 @@ "title": "Tenester" }, "states": { + "no_entities": "Ingen oppføringar", "title": "Statusar" }, "templates": { @@ -1361,7 +1377,8 @@ "required": "Påkrevd" }, "entities": { - "description": "Oppføringskortet er den vanlegaste korttypen. Den kan gruppere ting inn i lister." + "description": "Oppføringskortet er den vanlegaste korttypen. Den kan gruppere ting inn i lister.", + "name": "Oppføringar" }, "entity-filter": { "description": "Oppføringsfilterkortet let deg definere ei liste med oppføringar som du vil vise berre når dei har ein spesiell tilstand." @@ -1478,7 +1495,13 @@ }, "reload_lovelace": "Omlast Lovelace", "unused_entities": { - "domain": "Domene" + "domain": "Domene", + "entity": "Oppføring ", + "entity_id": "Oppførings-ID", + "last_changed": "Sist endra", + "no_data": "Ingen ubrukte oppføringar funne", + "search": "Søk i oppføringar", + "title": "Ubrukte oppføringar" }, "warning": { "entity_non_numeric": "Oppføringa er ikkje numerisk: {entity}", diff --git a/translations/frontend/pt.json b/translations/frontend/pt.json index 911e0e5131..e47bae1da7 100644 --- a/translations/frontend/pt.json +++ b/translations/frontend/pt.json @@ -1648,6 +1648,7 @@ }, "ozw": { "common": { + "node_id": "ID de nó", "ozw_instance": "Instância OpenZWave", "zwave": "Z-Wave" }, From 6835b73e4928778b3b9eba17b14af0014675df58 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Wed, 19 Aug 2020 00:33:28 +0000 Subject: [PATCH 32/38] [ci skip] Translation update --- translations/frontend/ca.json | 4 ++ translations/frontend/es.json | 31 ++++++++++++++ translations/frontend/fr.json | 22 ++++++++++ translations/frontend/fy.json | 69 +++++++++++++++++++++++++++++- translations/frontend/ko.json | 4 +- translations/frontend/lb.json | 68 ++++++++++++++++++++++++++++- translations/frontend/nb.json | 31 ++++++++++++++ translations/frontend/pt.json | 6 +++ translations/frontend/ru.json | 31 ++++++++++++++ translations/frontend/zh-Hans.json | 31 ++++++++++++++ 10 files changed, 292 insertions(+), 5 deletions(-) diff --git a/translations/frontend/ca.json b/translations/frontend/ca.json index cb4122cf4a..28184bc2eb 100644 --- a/translations/frontend/ca.json +++ b/translations/frontend/ca.json @@ -1656,6 +1656,10 @@ "node_failed": "Ha fallat el node", "stage": "Etapa", "zwave_info": "Informació Z-Wave" + }, + "refresh_node": { + "node_status": "Estat del node", + "step": "Pas" } }, "person": { diff --git a/translations/frontend/es.json b/translations/frontend/es.json index 6777ea2763..b7a8f86dba 100644 --- a/translations/frontend/es.json +++ b/translations/frontend/es.json @@ -1656,6 +1656,37 @@ "node_failed": "Error en el Nodo", "stage": "Etapa", "zwave_info": "Información Z-Wave" + }, + "node_query_stages": { + "associations": "Refrescando grupos de asociaciones y miembros", + "cacheload": "Cargando información del archivo de caché de OpenZWave. Los nodos con batería permanecerán en esta etapa hasta que el nodo se active.", + "complete": "El proceso de entrevista está completo", + "configuration": "Obteniendo valores de configuración del nodo", + "dynamic": "Obteniendo valores que cambian con frecuencia del nodo", + "instances": "Obteniendo detalles sobre qué instancias o canales admite un dispositivo", + "manufacturerspecific1": "Obteniendo del nodo los códigos de identificación de producto y del fabricante", + "manufacturerspecific2": "Obteniendo del nodo códigos de identificación de producto y del fabricante adicionales", + "neighbors": "Obteniendo una lista de los vecinos del nodo", + "nodeinfo": "Obteniendo clases de órdenes admitidas por el nodo", + "nodeplusinfo": "Obteniendo información Z-Wave+ del nodo", + "probe": "Comprobando si el nodo está despierto/vivo", + "protocolinfo": "Obteniendo las capacidades básicas de Z-Wave de este nodo desde el controlador", + "session": "Obteniendo valores que cambian con poca frecuencia del nodo", + "static": "Obteniendo valores estáticos del dispositivo", + "versions": "Obteniendo información sobre versiones de firmware y clases de órdenes", + "wakeup": "Configurando soporte para colas de despertador y mensajes" + }, + "refresh_node": { + "battery_note": "Si el nodo funciona con batería, asegúrate de despertarlo antes de continuar", + "complete": "Refresco del Nodo Finalizado", + "description": "Esto le indicará a OpenZWave que vuelva a entrevistar un nodo y actualice las clases de órdenes, las capacidades y los valores del mismo.", + "node_status": "Estado del Nodo", + "refreshing_description": "Refrescando la información del nodo ...", + "start_refresh_button": "Iniciar Refresco", + "step": "Paso", + "title": "Refrescar Información del Nodo", + "wakeup_header": "Instrucciones para despertar a", + "wakeup_instructions_source": "Las instrucciones para despertarlo se obtienen de la base de datos de dispositivos de la comunidad OpenZWave." } }, "person": { diff --git a/translations/frontend/fr.json b/translations/frontend/fr.json index dd5e569a1d..5a6dcc52ca 100644 --- a/translations/frontend/fr.json +++ b/translations/frontend/fr.json @@ -1656,6 +1656,28 @@ "node_failed": "Nœud Défaillant", "stage": "Étape", "zwave_info": "Informations Z-Wave" + }, + "node_query_stages": { + "associations": "Rafraîchissement les associations et les membres", + "cacheload": "Chargement des informations à partir du fichier de cache OpenZWave. Les nœuds de batterie resteront à cette étape jusqu'à ce que le nœud se réveille.", + "complete": "Le processus d'interrogation est terminé", + "configuration": "Obtention la configuration à partir du nœud", + "dynamic": "Obtention de valeurs fréquemment modifiées du nœud", + "neighbors": "Obtenir une liste des nœuds voisins", + "session": "Obtention de valeurs rarement modifiées du nœud", + "static": "Obtention des valeurs statiques de l'appareil" + }, + "refresh_node": { + "battery_note": "Si le nœud est alimenté par batterie, assurez-vous de l'activer avant de continuer", + "complete": "Actualisation du nœud terminée", + "description": "Cela indiquera à OpenZWave de réinterroger le nœud et de le mettre à jour (commandes, possibilités et valeurs).", + "node_status": "État du nœud", + "refreshing_description": "Rafraîchissement des informations sur le nœud...", + "start_refresh_button": "Démarrer l'actualisation", + "step": "Étape", + "title": "Actualiser les informations du nœud", + "wakeup_header": "Instructions de réveil pour", + "wakeup_instructions_source": "Les instructions de réveil proviennent de la base de données de la communauté OpenZWave." } }, "person": { diff --git a/translations/frontend/fy.json b/translations/frontend/fy.json index 119c6b7034..918eb995c3 100644 --- a/translations/frontend/fy.json +++ b/translations/frontend/fy.json @@ -15,6 +15,9 @@ } }, "state_badge": { + "alarm_control_panel": { + "armed_custom_bypass": "Ynskeakele" + }, "default": { "unknown": "Ûnbek." }, @@ -24,6 +27,10 @@ }, "state": { "alarm_control_panel": { + "armed": "Ynskeakele", + "armed_away": "Ynskeakele ôfwêzich", + "armed_home": "Ynskeakele thús", + "armed_night": "Ynskeakele nacht", "triggered": "Aktivearre" }, "automation": { @@ -86,6 +93,7 @@ }, "default": { "off": "Út", + "on": "Oan", "unavailable": "Net beskikber", "unknown": "Ûnbekend" }, @@ -137,10 +145,32 @@ } }, "ui": { + "card": { + "script": { + "cancel": "Annulearje", + "cancel_multiple": "Annulearje {number}" + }, + "timer": { + "actions": { + "cancel": "Annulearje" + } + }, + "weather": { + "attributes": { + "precipitation": "Delslach" + }, + "high": "Heech", + "low": "Leech" + } + }, "common": { + "cancel": "Annulearje", "loading": "Oan it laden" }, "dialogs": { + "generic": { + "cancel": "Annulearje" + }, "zha_device_info": { "zha_device_card": { "device_name_placeholder": "Feroarje apparaatnamme" @@ -173,6 +203,7 @@ "start": "Opstarte" }, "mqtt": { + "label": "MQTT", "payload": "Payload (opsjoneel)" }, "state": { @@ -181,6 +212,11 @@ } } } + }, + "picker": { + "headers": { + "name": "Namme" + } } }, "helpers": { @@ -200,8 +236,30 @@ } } }, + "mqtt": { + "title": "MQTT" + }, + "scene": { + "picker": { + "headers": { + "name": "Namme" + } + } + }, "script": { - "description": "Meitsje en bewurkje scripts" + "description": "Meitsje en bewurkje scripts", + "picker": { + "headers": { + "name": "Namme" + } + } + }, + "users": { + "picker": { + "headers": { + "name": "Namme" + } + } }, "zha": { "groups": { @@ -211,6 +269,9 @@ "zwave": { "node_config": { "config_value": "Konfiguraasje wearde" + }, + "services": { + "cancel_command": "Opdracht annulearje" } } }, @@ -228,10 +289,14 @@ "playback_title": "Berjocht ôfspylje" }, "profile": { + "dashboard": { + "dropdown_label": "Dashboard", + "header": "Dashboard" + }, "themes": { "dark_mode": { "dark": "Tsjuster", - "light": "ljocht" + "light": "Ljocht" }, "primary_color": "Primêre kleur" } diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json index 0a74b9f1ea..f525c91cad 100644 --- a/translations/frontend/ko.json +++ b/translations/frontend/ko.json @@ -870,11 +870,11 @@ "label": "횟수" }, "until": { - "conditions": "~일 때 까지 (조건)", + "conditions": "~일 때 까지 조건", "label": "~일 때 까지" }, "while": { - "conditions": "~인 동안 (조건)", + "conditions": "~인 동안 조건", "label": "~인 동안" } } diff --git a/translations/frontend/lb.json b/translations/frontend/lb.json index 39803ff861..91c2754fc2 100644 --- a/translations/frontend/lb.json +++ b/translations/frontend/lb.json @@ -833,6 +833,15 @@ "name": "Aktioun", "type_select": "Aktioun Typ", "type": { + "choose": { + "add_option": "Optioun dobäisetzen", + "conditions": "Konditiounen", + "default": "Standard Aktiounen", + "label": "Auswielen", + "option": "Optioun {number}", + "remove_option": "Optioun läschen", + "sequence": "Aktiounen" + }, "condition": { "label": "Konditioun" }, @@ -852,6 +861,24 @@ "label": "Evenement starten", "service_data": "Service-Donnéeën" }, + "repeat": { + "label": "Widderhuelen", + "sequence": "Aktiounen", + "type_select": "Widderhuelen Typ", + "type": { + "count": { + "label": "Ziel" + }, + "until": { + "conditions": "Bis Konditiounen", + "label": "Bis" + }, + "while": { + "conditions": "Während Konditiounen", + "label": "Während" + } + } + }, "scene": { "label": "Zeen aktivéieren" }, @@ -1619,6 +1646,30 @@ "title": "MQTT", "topic": "Sujet" }, + "ozw": { + "common": { + "node_id": "Node ID", + "zwave": "Z-Wave" + }, + "node_query_stages": { + "complete": "Interview Prozess ass komplett", + "configuration": "Konfiguratiounswerter vum Node kréien", + "instances": "Detailer kréien iwwert wéieng Instanzen oder Kanäl en Apparat ënnerstëtzt", + "manufacturerspecific2": "Zousätzlech Hiersteller a Produkt ID Coden vum Node kréien", + "neighbors": "Eng Lëscht vun den Nopere vum Node kréien", + "static": "Statesch Wäerter vum Apparat kréien", + "versions": "Informatioun kréien iwwert Firmware a Kommando Klass Versiounen" + }, + "refresh_node": { + "complete": "Aktualiséierung vun den Node Informatioune komplett", + "node_status": "Status vum Node", + "refreshing_description": "Node Informatiounen aktualiséieren...", + "start_refresh_button": "Aktualiséierung starten", + "step": "Schrëtt", + "title": "Node Informatiounen aktualiséieren", + "wakeup_header": "Instruktioune fir d'erwäche vun" + } + }, "person": { "add_person": "Persoun dobäisetzen", "caption": "Persounen", @@ -2385,6 +2436,9 @@ "para_migrate": "Home Assistant kann ID's zu all äre Kaarten automatesch dobäisetzen andeem dir de Knäppche 'Konfiguratioun migréieren' dréckt.", "para_no_id": "Dëst Element huet keng ID. Definéiert w.e.g. eng ID fir dëst Element am 'ui-lovelace.yaml'." }, + "move_card": { + "header": "Vue auswielen wou d'Kaart geréckelt soll ginn." + }, "raw_editor": { "confirm_remove_config_text": "Mir erstellen automatesch är Lovelace Usiichte mat äre Beräicher an Apparaten wann dir är Lovelace Konfiguratioun läscht.", "confirm_remove_config_title": "Sécher fir är Lovelace Konfiguratioun ze läschen? Mir erstellen automatesch är Lovelace Usiichte mat äre Beräicher an Apparaten.", @@ -2412,6 +2466,10 @@ "yaml_control": "Fir d'Kontroll am YAML Modus z'iwwerhuelen, erstell ee YAML Fichier mam Numm deen an der Konfiguratioun vun dësem Tableau de Bord uginn ass, oder de Standard 'ui-lovelace.yaml'", "yaml_mode": "Du benotz de YAML Modus fir dësen Tableau de Bord, dëst bedeit dass du d'Lovelace Konfiguratioun net kanns aus dem Benotzer Interface änneren. Wann's du Lovelace vum Benotzer Interface aus wëlls änneren, läsch de 'mode: yaml' aus denger Lovelace Konfiguratioun am 'configuration.yaml'" }, + "select_view": { + "dashboard_label": "Tableau de Bord", + "header": "Vue auswielen" + }, "suggest_card": { "add": "Zu Lovelace bäisetzen", "create_own": "Aner Kaart auswielen", @@ -2729,10 +2787,18 @@ "header": "Verbindung autmatesch zoumaachen" }, "themes": { + "accent_color": "Faarf vum Accent", + "dark_mode": { + "auto": "Auto", + "dark": "Däischter", + "light": "Hell" + }, "dropdown_label": "Thema", "error_no_theme": "Keen Thema disponibel", "header": "Thema", - "link_promo": "Méi iwwert Thema liesen" + "link_promo": "Méi iwwert Thema liesen", + "primary_color": "Primär Faarf", + "reset": "Reset" }, "vibrate": { "description": "Vibratioun op dësem Apparat un oder ausschalte wann aner Apparater gesteiert ginn.", diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json index 36496f4f21..6a5167233e 100644 --- a/translations/frontend/nb.json +++ b/translations/frontend/nb.json @@ -1656,6 +1656,37 @@ "node_failed": "Noden mislyktes", "stage": "Scene", "zwave_info": "Z-Wave Info" + }, + "node_query_stages": { + "associations": "Oppdatere tilknytningsgrupper og medlemskap", + "cacheload": "Laste inn informasjon fra Cachefilen for OpenZWave. Batterinoder vil bli på dette stadiet til noden våkner.", + "complete": "Intervjuprosessen er fullført", + "configuration": "Innhenting av konfigurasjonsverdier fra noden", + "dynamic": "Få ofte endrede verdier fra noden", + "instances": "Innhenting av detaljer om hvilke forekomster eller kanaler en enhet støtter", + "manufacturerspecific1": "Hente produsent- og produkt-ID-koder fra noden", + "manufacturerspecific2": "Hente flere produsent- og produkt-ID-koder fra noden", + "neighbors": "Få en liste over nodens naboer", + "nodeinfo": "Innhenting av støttede kommandoklasser fra noden", + "nodeplusinfo": "Innhenting av Z-Wave + informasjon fra noden", + "probe": "Kontrollere om noden er våken/levende", + "protocolinfo": "Få grunnleggende Z-Wave-funksjoner i denne noden fra kontrolleren", + "session": "\nFå sjelden endrede verdier fra noden", + "static": "Innhenting av statiske verdier fra enheten", + "versions": "Hente informasjon om fastvare- og kommandoklasseversjoner", + "wakeup": "Sette opp støtte for vekkingskøer og meldinger" + }, + "refresh_node": { + "battery_note": "Hvis noden er batteridrevet, må du passe på å vekke den før du fortsetter", + "complete": "Node oppdatering fullført", + "description": "Dette vil fortelle OpenZWave å re-intervjue en node og oppdatere nodens kommandoklasser, evner og verdier.", + "node_status": "Node-status", + "refreshing_description": "Oppdaterer nodeinformasjon...", + "start_refresh_button": "Start oppdatering", + "step": "Steg", + "title": "Oppdater nodeinformasjon", + "wakeup_header": "Wakeup Instruksjoner for", + "wakeup_instructions_source": "Wakeup-instruksjoner hentes fra OpenZWave-fellesskapets enhetsdatabase." } }, "person": { diff --git a/translations/frontend/pt.json b/translations/frontend/pt.json index e47bae1da7..06c63122e4 100644 --- a/translations/frontend/pt.json +++ b/translations/frontend/pt.json @@ -1655,6 +1655,12 @@ "device_info": { "node_failed": "Falha no nó", "zwave_info": "Informações sobre Z-Wave" + }, + "refresh_node": { + "node_status": "Estado do Nó", + "refreshing_description": "A atualizar as informações do nó ...", + "start_refresh_button": "Iniciar atualização", + "step": "Passo" } }, "person": { diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json index 6abedb94c4..208f067158 100644 --- a/translations/frontend/ru.json +++ b/translations/frontend/ru.json @@ -1656,6 +1656,37 @@ "node_failed": "Ошибка узла", "stage": "Этап", "zwave_info": "Информация о Z-Wave" + }, + "node_query_stages": { + "associations": "Обновление ассоциативных групп и членства", + "cacheload": "Загрузка информации из кеш-файла OpenZWave. Узлы батареи останутся на этом этапе, пока узел не проснется.", + "complete": "Процесс интервьюирования завершен", + "configuration": "Получение значений конфигурации от узла", + "dynamic": "Получение часто меняющихся значений от узла", + "instances": "Получение сведений о том, какие экземпляры или каналы поддерживает устройство", + "manufacturerspecific1": "Получение идентификационных кодов производителя и продукта от узла", + "manufacturerspecific2": "Получение дополнительных кодов производителя и идентификатора продукта от узла", + "neighbors": "Получение списка соседних узлов", + "nodeinfo": "Получение поддерживаемых классов команд от узла", + "nodeplusinfo": "Получение информации Z-Wave+ от узла", + "probe": "Проверка активности узла", + "protocolinfo": "Получение базовых возможностей этого узла от контроллера", + "session": "Получение редко меняющихся значений от узла", + "static": "Получение статических значений от устройства", + "versions": "Получение информации о версиях прошивки и классов команд", + "wakeup": "Настройка поддержки очередей пробуждения и сообщений" + }, + "refresh_node": { + "battery_note": "Если узел работает от батареи, обязательно разбудите его, прежде чем продолжить", + "complete": "Обновление узла завершено", + "description": "Повторный опрос узла и обновление классов команд, возможностей и значений узла.", + "node_status": "Статус узла", + "refreshing_description": "Обновление информации об узле ...", + "start_refresh_button": "Начать обновление", + "step": "Шаг", + "title": "Обновить информацию об узле", + "wakeup_header": "Инструкции по пробуждению для", + "wakeup_instructions_source": "Инструкции по пробуждению взяты из базы данных устройств сообщества OpenZWave." } }, "person": { diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json index d7ccb3da20..6f350d1bb0 100644 --- a/translations/frontend/zh-Hans.json +++ b/translations/frontend/zh-Hans.json @@ -1656,6 +1656,37 @@ "node_failed": "节点故障", "stage": "阶段", "zwave_info": "Z-Wave 信息" + }, + "node_query_stages": { + "associations": "正在刷新关联组和成员", + "cacheload": "正在从 OpenZWave 缓存文件加载信息。电池供电的节点将停留在此阶段,直到节点唤醒。", + "complete": "协商完成", + "configuration": "正在从节点获取配置值", + "dynamic": "正在从节点获取频繁更改的值", + "instances": "正在获取设备支持的实例或通道的详细信息", + "manufacturerspecific1": "正在从节点获取制造商和产品 ID 代码", + "manufacturerspecific2": "从节点获取附加制造商和产品 ID 代码", + "neighbors": "正在获取邻居节点的列表", + "nodeinfo": "正在从节点获取受支持的命令类", + "nodeplusinfo": "正在从节点获取 Z-Wave+ 信息", + "probe": "正在检查节点是否处于唤醒状态", + "protocolinfo": "正在从控制器获取此节点的基本 Z-Wave 功能", + "session": "正在从节点获取不经常更改的值", + "static": "正在从设备获取静态值", + "versions": "正在获取固件和命令类版本信息", + "wakeup": "正在设置对唤醒队列和消息的支持" + }, + "refresh_node": { + "battery_note": "如果节点由电池供电,请确保在继续操作之前将其唤醒", + "complete": "节点刷新完成", + "description": "这将通知 OpenZWave 重新访问节点并更新节点的命令类、功能和值。", + "node_status": "节点状态", + "refreshing_description": "正在刷新节点信息...", + "start_refresh_button": "开始刷新", + "step": "步骤", + "title": "刷新节点信息", + "wakeup_header": "唤醒方法:", + "wakeup_instructions_source": "唤醒方法来自 OpenZWave 社区设备数据库。" } }, "person": { From e352768388a48b15c4717594909600609aabb0b1 Mon Sep 17 00:00:00 2001 From: Zack Arnett Date: Wed, 19 Aug 2020 04:02:21 -0500 Subject: [PATCH 33/38] Save Config Dialog - Convert to MWC (#6590) --- .../lovelace/editor/hui-dialog-save-config.ts | 139 +++++++++--------- 1 file changed, 73 insertions(+), 66 deletions(-) diff --git a/src/panels/lovelace/editor/hui-dialog-save-config.ts b/src/panels/lovelace/editor/hui-dialog-save-config.ts index 83c46f3593..f056413258 100644 --- a/src/panels/lovelace/editor/hui-dialog-save-config.ts +++ b/src/panels/lovelace/editor/hui-dialog-save-config.ts @@ -1,6 +1,5 @@ import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import "../../../components/ha-circular-progress"; +import "@material/mwc-icon-button/mwc-icon-button"; import { css, CSSResult, @@ -9,25 +8,28 @@ import { LitElement, property, internalProperty, - query, TemplateResult, } from "lit-element"; +import { mdiHelpCircle } from "@mdi/js"; import { fireEvent } from "../../../common/dom/fire_event"; -import "../../../components/dialog/ha-paper-dialog"; -import type { HaPaperDialog } from "../../../components/dialog/ha-paper-dialog"; -import "../../../components/ha-switch"; -import "../../../components/ha-formfield"; -import "../../../components/ha-yaml-editor"; -import type { PolymerChangedEvent } from "../../../polymer-types"; import { haStyleDialog } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import type { SaveDialogParams } from "./show-save-config-dialog"; import { computeRTLDirection } from "../../../common/util/compute_rtl"; +import type { HassDialog } from "../../../dialogs/make-dialog-manager"; +import "../../../components/ha-switch"; +import "../../../components/ha-formfield"; +import "../../../components/ha-yaml-editor"; +import "../../../components/ha-svg-icon"; +import "../../../components/ha-dialog"; +import "../../../components/ha-circular-progress"; const EMPTY_CONFIG = { views: [] }; +const coreDocumentationURLBase = "https://www.home-assistant.io/lovelace/"; + @customElement("hui-dialog-save-config") -export class HuiSaveConfig extends LitElement { +export class HuiSaveConfig extends LitElement implements HassDialog { @property({ attribute: false }) public hass?: HomeAssistant; @internalProperty() private _params?: SaveDialogParams; @@ -36,18 +38,20 @@ export class HuiSaveConfig extends LitElement { @internalProperty() private _saving: boolean; - @query("ha-paper-dialog") private _dialog?: HaPaperDialog; - public constructor() { super(); this._saving = false; } - public async showDialog(params: SaveDialogParams): Promise { + public showDialog(params: SaveDialogParams): void { this._params = params; this._emptyConfig = false; - await this.updateComplete; - this._dialog!.open(); + } + + public closeDialog(): boolean { + this._params = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + return true; } protected render(): TemplateResult { @@ -55,15 +59,27 @@ export class HuiSaveConfig extends LitElement { return html``; } return html` - + + + + `} > -

- ${this.hass!.localize("ui.panel.lovelace.editor.save_config.header")} -

- +

${this.hass!.localize("ui.panel.lovelace.editor.save_config.para")}

@@ -105,55 +121,46 @@ export class HuiSaveConfig extends LitElement {

`} - -
- ${this._params.mode === "storage" - ? html` - ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.cancel" - )} - - - - ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.save" - )} - - ` - : html` - ${this.hass!.localize( - "ui.panel.lovelace.editor.save_config.close" - )} - - `}
- + ${this._params.mode === "storage" + ? html` + ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.cancel" + )} + + + + ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.save" + )} + + ` + : html` + ${this.hass!.localize( + "ui.panel.lovelace.editor.save_config.close" + )} + + `} + `; } - private _closeDialog(): void { - this._dialog!.close(); - } - - private _openedChanged(ev: PolymerChangedEvent): void { - if (!ev.detail.value) { - this._params = undefined; + private _close(ev?: Event) { + if (ev) { + ev.stopPropagation(); } - } - - private _editorRefreshed() { - fireEvent(this._dialog! as HTMLElement, "iron-resize"); + this.closeDialog(); } private _emptyConfigChanged(ev) { @@ -172,7 +179,7 @@ export class HuiSaveConfig extends LitElement { ); lovelace.setEditMode(true); this._saving = false; - this._closeDialog(); + this.closeDialog(); } catch (err) { alert(`Saving failed: ${err.message}`); this._saving = false; From 0bc4b3d0faeac45111f5c82af96d0c801ca95516 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 19 Aug 2020 11:04:05 +0200 Subject: [PATCH 34/38] Adds theming and dark mode to code editor (#6547) --- src/components/ha-code-editor.ts | 101 +++++++++++++++++++++++++++++-- src/resources/styles.ts | 18 ++++++ 2 files changed, 113 insertions(+), 6 deletions(-) diff --git a/src/components/ha-code-editor.ts b/src/components/ha-code-editor.ts index aac917e31a..d4d74adef5 100644 --- a/src/components/ha-code-editor.ts +++ b/src/components/ha-code-editor.ts @@ -101,11 +101,6 @@ export class HaCodeEditor extends UpdatingElement { .CodeMirror-scroll { max-height: var(--code-mirror-max-height, --code-mirror-height); } - .CodeMirror-gutters { - border-right: 1px solid var(--paper-input-container-color, var(--secondary-text-color)); - background-color: var(--paper-dialog-background-color, var(--primary-background-color)); - transition: 0.2s ease border-right; - } :host(.error-state) .CodeMirror-gutters { border-color: var(--error-state-color, red); } @@ -113,7 +108,7 @@ export class HaCodeEditor extends UpdatingElement { border-right: 2px solid var(--paper-input-container-focus-color, var(--primary-color)); } .CodeMirror-linenumber { - color: var(--paper-dialog-color, var(--primary-text-color)); + color: var(--paper-dialog-color, var(--secondary-text-color)); } .rtl .CodeMirror-vscrollbar { right: auto; @@ -122,6 +117,100 @@ export class HaCodeEditor extends UpdatingElement { .rtl-gutter { width: 20px; } + .CodeMirror-gutters { + border-right: 1px solid var(--paper-input-container-color, var(--secondary-text-color)); + background-color: var(--paper-dialog-background-color, var(--primary-background-color)); + transition: 0.2s ease border-right; + } + .cm-s-default.CodeMirror { + background-color: var(--card-background-color); + color: var(--primary-text-color); + } + .cm-s-default .CodeMirror-cursor { + border-left: 1px solid var(--secondary-text-color); + } + + .cm-s-default div.CodeMirror-selected, .cm-s-default.CodeMirror-focused div.CodeMirror-selected { + background: rgba(var(--rgb-primary-color), 0.2); + } + + .cm-s-default .CodeMirror-line::selection, + .cm-s-default .CodeMirror-line>span::selection, + .cm-s-default .CodeMirror-line>span>span::selection { + background: rgba(var(--rgb-primary-color), 0.2); + } + + .cm-s-default .cm-keyword { + color: var(--codemirror-keyword, #6262FF); + } + + .cm-s-default .cm-operator { + color: var(--codemirror-operator, #cda869); + } + + .cm-s-default .cm-variable-2 { + color: var(--codemirror-variable-2, #690); + } + + .cm-s-default .cm-builtin { + color: var(--codemirror-builtin, #9B7536); + } + + .cm-s-default .cm-atom { + color: var(--codemirror-atom, #F90); + } + + .cm-s-default .cm-number { + color: var(--codemirror-number, #ca7841); + } + + .cm-s-default .cm-def { + color: var(--codemirror-def, #8DA6CE); + } + + .cm-s-default .cm-string { + color: var(--codemirror-string, #07a); + } + + .cm-s-default .cm-string-2 { + color: var(--codemirror-string-2, #bd6b18); + } + + .cm-s-default .cm-comment { + color: var(--codemirror-comment, #777); + } + + .cm-s-default .cm-variable { + color: var(--codemirror-variable, #07a); + } + + .cm-s-default .cm-tag { + color: var(--codemirror-tag, #997643); + } + + .cm-s-default .cm-meta { + color: var(--codemirror-meta, #000); + } + + .cm-s-default .cm-attribute { + color: var(--codemirror-attribute, #d6bb6d); + } + + .cm-s-default .cm-property { + color: var(--codemirror-property, #905); + } + + .cm-s-default .cm-qualifier { + color: var(--codemirror-qualifier, #690); + } + + .cm-s-default .cm-variable-3 { + color: var(--codemirror-variable-3, #07a); + } + + .cm-s-default .cm-type { + color: var(--codemirror-type, #07a); + } `; this.codemirror = codeMirror(shadowRoot, { diff --git a/src/resources/styles.ts b/src/resources/styles.ts index 316ccf77e1..89699a83a2 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -11,6 +11,24 @@ export const darkStyles = { "switch-unchecked-button-color": "#999999", "switch-unchecked-track-color": "#9b9b9b", "divider-color": "rgba(225, 225, 225, .12)", + "codemirror-keyword": "#C792EA", + "codemirror-operator": "#89DDFF", + "codemirror-variable": "#f07178", + "codemirror-variable-2": "#EEFFFF", + "codemirror-variable-3": "#DECB6B", + "codemirror-builtin": "#FFCB6B", + "codemirror-atom": "#F78C6C", + "codemirror-number": "#FF5370", + "codemirror-def": "#82AAFF", + "codemirror-string": "#C3E88D", + "codemirror-string-2": "#f07178", + "codemirror-comment": "#545454", + "codemirror-tag": "#FF5370", + "codemirror-meta": "#FFCB6B", + "codemirror-attribute": "#C792EA", + "codemirror-property": "#C792EA", + "codemirror-qualifier": "#DECB6B", + "codemirror-type": "#DECB6B", }; export const derivedStyles = { From f928a8e58e8cb4561b67f4a8fad138f51d3dad0d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Wed, 19 Aug 2020 11:33:18 +0200 Subject: [PATCH 35/38] Add picture upload component (#6646) Co-authored-by: Bram Kragten --- package.json | 1 + src/components/ha-picture-upload.ts | 226 ++++++++++++++++++ src/data/image.ts | 54 +++++ src/data/person.ts | 2 + .../image-cropper-dialog.ts | 136 +++++++++++ .../show-image-cropper-dialog.ts | 30 +++ .../config/person/dialog-person-detail.ts | 33 ++- src/panels/config/person/ha-config-person.ts | 39 ++- src/state/connection-mixin.ts | 6 +- src/translations/en.json | 7 + yarn.lock | 11 +- 11 files changed, 532 insertions(+), 13 deletions(-) create mode 100644 src/components/ha-picture-upload.ts create mode 100644 src/data/image.ts create mode 100644 src/dialogs/image-cropper-dialog/image-cropper-dialog.ts create mode 100644 src/dialogs/image-cropper-dialog/show-image-cropper-dialog.ts diff --git a/package.json b/package.json index 47bf3b8ec9..f2fe5f1c72 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "codemirror": "^5.49.0", "comlink": "^4.3.0", "cpx": "^1.5.0", + "cropperjs": "^1.5.7", "deep-clone-simple": "^1.1.1", "deep-freeze": "^0.0.1", "es6-object-assign": "^1.1.0", diff --git a/src/components/ha-picture-upload.ts b/src/components/ha-picture-upload.ts new file mode 100644 index 0000000000..411984d555 --- /dev/null +++ b/src/components/ha-picture-upload.ts @@ -0,0 +1,226 @@ +import "@material/mwc-icon-button/mwc-icon-button"; +import { mdiClose, mdiImagePlus } from "@mdi/js"; +import "@polymer/iron-input/iron-input"; +import "@polymer/paper-input/paper-input-container"; +import { + css, + customElement, + html, + internalProperty, + LitElement, + property, + PropertyValues, + TemplateResult, +} from "lit-element"; +import { classMap } from "lit-html/directives/class-map"; +import { fireEvent } from "../common/dom/fire_event"; +import { createImage, generateImageThumbnailUrl } from "../data/image"; +import { HomeAssistant } from "../types"; +import "./ha-circular-progress"; +import "./ha-svg-icon"; +import { + showImageCropperDialog, + CropOptions, +} from "../dialogs/image-cropper-dialog/show-image-cropper-dialog"; + +@customElement("ha-picture-upload") +export class HaPictureUpload extends LitElement { + public hass!: HomeAssistant; + + @property() public value: string | null = null; + + @property() public label?: string; + + @property({ type: Boolean }) public crop = false; + + @property({ attribute: false }) public cropOptions?: CropOptions; + + @property({ type: Number }) public size = 512; + + @internalProperty() private _error = ""; + + @internalProperty() private _uploading = false; + + @internalProperty() private _drag = false; + + protected updated(changedProperties: PropertyValues) { + if (changedProperties.has("_drag")) { + (this.shadowRoot!.querySelector( + "paper-input-container" + ) as any)._setFocused(this._drag); + } + } + + public render(): TemplateResult { + return html` + ${this._uploading + ? html`` + : html` + ${this._error ? html`
${this._error}
` : ""} + + `} + `; + } + + private _handleDrop(ev: DragEvent) { + ev.preventDefault(); + ev.stopPropagation(); + if (ev.dataTransfer?.files) { + if (this.crop) { + this._cropFile(ev.dataTransfer.files[0]); + } else { + this._uploadFile(ev.dataTransfer.files[0]); + } + } + this._drag = false; + } + + private _handleDragStart(ev: DragEvent) { + ev.preventDefault(); + ev.stopPropagation(); + this._drag = true; + } + + private _handleDragEnd(ev: DragEvent) { + ev.preventDefault(); + ev.stopPropagation(); + this._drag = false; + } + + private async _handleFilePicked(ev) { + if (this.crop) { + this._cropFile(ev.target.files[0]); + } else { + this._uploadFile(ev.target.files[0]); + } + } + + private async _cropFile(file: File) { + if (!["image/png", "image/jpeg", "image/gif"].includes(file.type)) { + this._error = this.hass.localize( + "ui.components.picture-upload.unsupported_format" + ); + return; + } + showImageCropperDialog(this, { + file, + options: this.cropOptions || { + round: false, + aspectRatio: NaN, + }, + croppedCallback: (croppedFile) => { + this._uploadFile(croppedFile); + }, + }); + } + + private async _uploadFile(file: File) { + if (!["image/png", "image/jpeg", "image/gif"].includes(file.type)) { + this._error = this.hass.localize( + "ui.components.picture-upload.unsupported_format" + ); + return; + } + this._uploading = true; + this._error = ""; + try { + const media = await createImage(this.hass, file); + this.value = generateImageThumbnailUrl(media.id, this.size); + fireEvent(this, "change"); + } catch (err) { + this._error = err.toString(); + } finally { + this._uploading = false; + } + } + + private _clearPicture(ev: Event) { + ev.preventDefault(); + this.value = null; + this._error = ""; + fireEvent(this, "change"); + } + + static get styles() { + return css` + .error { + color: var(--error-color); + } + paper-input-container { + position: relative; + padding: 8px; + margin: 0 -8px; + } + paper-input-container.dragged:before { + position: var(--layout-fit_-_position); + top: var(--layout-fit_-_top); + right: var(--layout-fit_-_right); + bottom: var(--layout-fit_-_bottom); + left: var(--layout-fit_-_left); + background: currentColor; + content: ""; + opacity: var(--dark-divider-opacity); + pointer-events: none; + border-radius: 4px; + } + img { + max-width: 125px; + max-height: 125px; + } + input.file { + display: none; + } + mwc-icon-button { + --mdc-icon-button-size: 24px; + --mdc-icon-size: 20px; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-picture-upload": HaPictureUpload; + } +} diff --git a/src/data/image.ts b/src/data/image.ts new file mode 100644 index 0000000000..b81499f002 --- /dev/null +++ b/src/data/image.ts @@ -0,0 +1,54 @@ +import { HomeAssistant } from "../types"; + +interface Image { + filesize: number; + name: string; + uploaded_at: string; // isoformat date + content_type: string; + id: string; +} + +export interface ImageMutableParams { + name: string; +} + +export const generateImageThumbnailUrl = (mediaId: string, size: number) => + `/api/image/serve/${mediaId}/${size}x${size}`; + +export const fetchImages = (hass: HomeAssistant) => + hass.callWS({ type: "image/list" }); + +export const createImage = async ( + hass: HomeAssistant, + file: File +): Promise => { + const fd = new FormData(); + fd.append("file", file); + const resp = await hass.fetchWithAuth("/api/image/upload", { + method: "POST", + body: fd, + }); + if (resp.status === 413) { + throw new Error("Uploaded image is too large"); + } else if (resp.status !== 200) { + throw new Error("Unknown error"); + } + return await resp.json(); +}; + +export const updateImage = ( + hass: HomeAssistant, + id: string, + updates: Partial +) => + hass.callWS({ + type: "image/update", + media_id: id, + ...updates, + }); + +export const deleteImage = (hass: HomeAssistant, id: string) => + hass.callWS({ + type: "image/delete", + media_id: id, + }); diff --git a/src/data/person.ts b/src/data/person.ts index 00e77a838f..eb3b358729 100644 --- a/src/data/person.ts +++ b/src/data/person.ts @@ -5,12 +5,14 @@ export interface Person { name: string; user_id?: string; device_trackers?: string[]; + picture?: string; } export interface PersonMutableParams { name: string; user_id: string | null; device_trackers: string[]; + picture: string | null; } export const fetchPersons = (hass: HomeAssistant) => diff --git a/src/dialogs/image-cropper-dialog/image-cropper-dialog.ts b/src/dialogs/image-cropper-dialog/image-cropper-dialog.ts new file mode 100644 index 0000000000..ed9e3a05aa --- /dev/null +++ b/src/dialogs/image-cropper-dialog/image-cropper-dialog.ts @@ -0,0 +1,136 @@ +import "@material/mwc-button/mwc-button"; +import Cropper from "cropperjs"; +// @ts-ignore +import cropperCss from "cropperjs/dist/cropper.css"; +import { + css, + CSSResult, + customElement, + html, + internalProperty, + LitElement, + property, + PropertyValues, + query, + TemplateResult, + unsafeCSS, +} from "lit-element"; +import "../../components/ha-dialog"; +import { haStyleDialog } from "../../resources/styles"; +import type { HomeAssistant } from "../../types"; +import { HaImageCropperDialogParams } from "./show-image-cropper-dialog"; +import { classMap } from "lit-html/directives/class-map"; + +@customElement("image-cropper-dialog") +export class HaImagecropperDialog extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @internalProperty() private _params?: HaImageCropperDialogParams; + + @internalProperty() private _open = false; + + @query("img") private _image!: HTMLImageElement; + + private _cropper?: Cropper; + + public showDialog(params: HaImageCropperDialogParams): void { + this._params = params; + this._open = true; + } + + public closeDialog() { + this._open = false; + this._params = undefined; + this._cropper?.destroy(); + } + + protected updated(changedProperties: PropertyValues) { + if (!changedProperties.has("_params") || !this._params) { + return; + } + if (!this._cropper) { + this._image.src = URL.createObjectURL(this._params.file); + this._cropper = new Cropper(this._image, { + aspectRatio: this._params.options.aspectRatio, + viewMode: 1, + dragMode: "move", + minCropBoxWidth: 50, + ready: () => { + URL.revokeObjectURL(this._image!.src); + }, + }); + } else { + this._cropper.replace(URL.createObjectURL(this._params.file)); + } + } + + protected render(): TemplateResult { + return html` +
+ +
+ + ${this.hass.localize("ui.common.cancel")} + + + ${this.hass.localize("ui.dialogs.image_cropper.crop")} + +
`; + } + + private _cropImage() { + this._cropper!.getCroppedCanvas().toBlob( + (blob) => { + if (!blob) { + return; + } + const file = new File([blob], this._params!.file.name, { + type: this._params!.options.type || this._params!.file.type, + }); + this._params!.croppedCallback(file); + this.closeDialog(); + }, + this._params!.options.type || this._params!.file.type, + this._params!.options.quality + ); + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + ${unsafeCSS(cropperCss)} + .container { + max-width: 640px; + } + img { + max-width: 100%; + } + .container.round .cropper-view-box, + .container.round .cropper-face { + border-radius: 50%; + } + .cropper-line, + .cropper-point, + .cropper-point.point-se::before { + background-color: var(--primary-color); + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "image-cropper-dialog": HaImagecropperDialog; + } +} diff --git a/src/dialogs/image-cropper-dialog/show-image-cropper-dialog.ts b/src/dialogs/image-cropper-dialog/show-image-cropper-dialog.ts new file mode 100644 index 0000000000..3ca19001c8 --- /dev/null +++ b/src/dialogs/image-cropper-dialog/show-image-cropper-dialog.ts @@ -0,0 +1,30 @@ +import { fireEvent } from "../../common/dom/fire_event"; + +export interface CropOptions { + round: boolean; + type?: "image/jpeg" | "image/png"; + quality?: number; + aspectRatio: number; +} + +export interface HaImageCropperDialogParams { + file: File; + options: CropOptions; + croppedCallback: (file: File) => void; +} + +const loadImageCropperDialog = () => + import( + /* webpackChunkName: "image-cropper-dialog" */ "./image-cropper-dialog" + ); + +export const showImageCropperDialog = ( + element: HTMLElement, + dialogParams: HaImageCropperDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "image-cropper-dialog", + dialogImport: loadImageCropperDialog, + dialogParams, + }); +}; diff --git a/src/panels/config/person/dialog-person-detail.ts b/src/panels/config/person/dialog-person-detail.ts index b146cf4074..94c50807c1 100644 --- a/src/panels/config/person/dialog-person-detail.ts +++ b/src/panels/config/person/dialog-person-detail.ts @@ -10,6 +10,8 @@ import { TemplateResult, } from "lit-element"; import memoizeOne from "memoize-one"; +import "../../../components/ha-picture-upload"; +import type { HaPictureUpload } from "../../../components/ha-picture-upload"; import "../../../components/entity/ha-entities-picker"; import { createCloseHeading } from "../../../components/ha-dialog"; import "../../../components/user/ha-user-picker"; @@ -18,9 +20,17 @@ import { PolymerChangedEvent } from "../../../polymer-types"; import { haStyleDialog } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { PersonDetailDialogParams } from "./show-dialog-person-detail"; +import { CropOptions } from "../../../dialogs/image-cropper-dialog/show-image-cropper-dialog"; const includeDomains = ["device_tracker"]; +const cropOptions: CropOptions = { + round: true, + type: "image/jpeg", + quality: 0.75, + aspectRatio: 1, +}; + class DialogPersonDetail extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -30,6 +40,8 @@ class DialogPersonDetail extends LitElement { @internalProperty() private _deviceTrackers!: string[]; + @internalProperty() private _picture!: string | null; + @internalProperty() private _error?: string; @internalProperty() private _params?: PersonDetailDialogParams; @@ -50,10 +62,12 @@ class DialogPersonDetail extends LitElement { this._name = this._params.entry.name || ""; this._userId = this._params.entry.user_id || undefined; this._deviceTrackers = this._params.entry.device_trackers || []; + this._picture = this._params.entry.picture || null; } else { this._name = ""; this._userId = undefined; this._deviceTrackers = []; + this._picture = null; } await this.updateComplete; } @@ -66,7 +80,7 @@ class DialogPersonDetail extends LitElement { return html` + + ) { + this._error = undefined; + this._picture = (ev.target as HaPictureUpload).value; + } + private async _updateEntry() { this._submitting = true; try { @@ -204,6 +231,7 @@ class DialogPersonDetail extends LitElement { name: this._name.trim(), device_trackers: this._deviceTrackers, user_id: this._userId || null, + picture: this._picture, }; if (this._params!.entry) { await this._params!.updateEntry(values); @@ -240,6 +268,9 @@ class DialogPersonDetail extends LitElement { .form { padding-bottom: 24px; } + ha-picture-upload { + display: block; + } ha-user-picker { margin-top: 16px; } diff --git a/src/panels/config/person/ha-config-person.ts b/src/panels/config/person/ha-config-person.ts index 94934fe200..764ae63b28 100644 --- a/src/panels/config/person/ha-config-person.ts +++ b/src/panels/config/person/ha-config-person.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-item/paper-item"; +import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-item-body"; import { css, @@ -32,6 +32,7 @@ import { } from "./show-dialog-person-detail"; import "../../../components/ha-svg-icon"; import { mdiPlus } from "@mdi/js"; +import { styleMap } from "lit-html/directives/style-map"; class HaConfigPerson extends LitElement { @property({ attribute: false }) public hass?: HomeAssistant; @@ -84,11 +85,20 @@ class HaConfigPerson extends LitElement { ${this._storageItems.map((entry) => { return html` - + + ${entry.picture + ? html`
` + : ""} ${entry.name} -
+ `; })} ${this._storageItems.length === 0 @@ -111,11 +121,20 @@ class HaConfigPerson extends LitElement { ${this._configItems.map((entry) => { return html` - + + ${entry.picture + ? html`
` + : ""} ${entry.name} -
+ `; })}
@@ -228,15 +247,21 @@ class HaConfigPerson extends LitElement { margin: 16px auto; overflow: hidden; } + .picture { + width: 40px; + height: 40px; + background-size: cover; + border-radius: 50%; + } .empty { text-align: center; padding: 8px; } - paper-item { + paper-icon-item { padding-top: 4px; padding-bottom: 4px; } - ha-card.storage paper-item { + ha-card.storage paper-icon-item { cursor: pointer; } `; diff --git a/src/state/connection-mixin.ts b/src/state/connection-mixin.ts index a5bb5daa2b..7af421029d 100644 --- a/src/state/connection-mixin.ts +++ b/src/state/connection-mixin.ts @@ -86,8 +86,10 @@ export const connectionMixin = >( }, callApi: async (method, path, parameters) => hassCallApi(auth, method, path, parameters), - fetchWithAuth: (path, init) => - fetchWithAuth(auth, `${auth.data.hassUrl}${path}`, init), + fetchWithAuth: ( + path: string, + init: Parameters[2] + ) => fetchWithAuth(auth, `${auth.data.hassUrl}${path}`, init), // For messages that do not get a response sendWS: (msg) => { if (__DEV__) { diff --git a/src/translations/en.json b/src/translations/en.json index 41f54a7386..cf43d60daa 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -299,6 +299,10 @@ "failed_create_area": "Failed to create area." } }, + "picture-upload": { + "label": "Picture", + "unsupported_format": "Unsupported format, please choose a JPEG, PNG or GIF image." + }, "date-range-picker": { "start_date": "Start date", "end_date": "End date", @@ -354,6 +358,9 @@ "default_confirmation_title": "Are you sure?", "close": "close" }, + "image_cropper": { + "crop": "Crop" + }, "more_info_control": { "dismiss": "Dismiss dialog", "settings": "Entity settings", diff --git a/yarn.lock b/yarn.lock index e6976c9b36..5fbc9e27ca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1345,7 +1345,7 @@ "@babel/runtime" "^7.7.2" core-js "^3.4.1" -"@material/animation@8.0.0-canary.096a7a066.0", "@material/animation@8.0.0-canary.a78ceb112.0", "@material/animation@=8.0.0-canary.096a7a066.0": +"@material/animation@8.0.0-canary.096a7a066.0", "@material/animation@8.0.0-canary.a78ceb112.0": version "8.0.0-canary.096a7a066.0" resolved "https://registry.yarnpkg.com/@material/animation/-/animation-8.0.0-canary.096a7a066.0.tgz#9c1b3d31858889e04e722ca8f1ade7ae3c54f7e6" integrity sha512-hGL6sMGcyd9JoxcyhRkAhD6KKQwZVRkhaFcra9YMBYHUbWRxfUbfDTjUZ3ZxmLDDcsjL4Hqjblet6Xmtq3Br5g== @@ -1463,7 +1463,7 @@ "@material/feature-targeting" "8.0.0-canary.096a7a066.0" "@material/theme" "8.0.0-canary.096a7a066.0" -"@material/feature-targeting@8.0.0-canary.096a7a066.0", "@material/feature-targeting@8.0.0-canary.a78ceb112.0", "@material/feature-targeting@=8.0.0-canary.096a7a066.0": +"@material/feature-targeting@8.0.0-canary.096a7a066.0", "@material/feature-targeting@8.0.0-canary.a78ceb112.0": version "8.0.0-canary.096a7a066.0" resolved "https://registry.yarnpkg.com/@material/feature-targeting/-/feature-targeting-8.0.0-canary.096a7a066.0.tgz#fca721c287b08e0868467ee60daa5d32aad16430" integrity sha512-5nxnG08PjdwhrLMNxfeCOImbdEtP/bVveOVr72hdqldHuwfnzNjp0lwWAAh/QZrpJNl4Ve2Cnp/LkRnlOELIkw== @@ -1839,7 +1839,7 @@ "@material/typography" "8.0.0-canary.096a7a066.0" tslib "^1.9.3" -"@material/theme@8.0.0-canary.096a7a066.0", "@material/theme@8.0.0-canary.a78ceb112.0", "@material/theme@=8.0.0-canary.096a7a066.0": +"@material/theme@8.0.0-canary.096a7a066.0", "@material/theme@8.0.0-canary.a78ceb112.0": version "8.0.0-canary.096a7a066.0" resolved "https://registry.yarnpkg.com/@material/theme/-/theme-8.0.0-canary.096a7a066.0.tgz#f657eaa545797ee3e6a2d96e4a61f844ad3dc425" integrity sha512-FdAUEjq7KJ835sobJQL0w0XWD5PabXl77HmBuy5F3bEYbYterWOutvuHbTkAEN6sTzgHCKhdoMubRxMKidqafA== @@ -4782,6 +4782,11 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" +cropperjs@^1.5.7: + version "1.5.7" + resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-1.5.7.tgz#b65019725bae1c6285e881fb661b2141fa57025b" + integrity sha512-sGj+G/ofKh+f6A4BtXLJwtcKJgMUsXYVUubfTo9grERiDGXncttefmue/fyQFvn8wfdyoD1KhDRYLfjkJFl0yw== + cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" From a0b28e8ad182a94f2ba75cdd8077a2a94a5574f6 Mon Sep 17 00:00:00 2001 From: HomeAssistant Azure Date: Thu, 20 Aug 2020 00:32:18 +0000 Subject: [PATCH 36/38] [ci skip] Translation update --- translations/frontend/cs.json | 4 +-- translations/frontend/el.json | 42 +++++++++++++++++++++++------- translations/frontend/en.json | 7 +++++ translations/frontend/lb.json | 20 ++++++++++++-- translations/frontend/zh-Hant.json | 31 ++++++++++++++++++++++ 5 files changed, 91 insertions(+), 13 deletions(-) diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json index 6ec56b85ff..884e231eb2 100644 --- a/translations/frontend/cs.json +++ b/translations/frontend/cs.json @@ -1769,9 +1769,9 @@ "core": "Znovu načíst umístění a přizpůsobení", "group": "Znovu načíst skupiny", "heading": "Konfigurace se načítá", - "input_boolean": "Znovu načíst pomocníky - čísla", + "input_boolean": "Znovu načíst pomocníky - přepínače", "input_datetime": "Znovu načíst pomocníky - data/časy", - "input_number": "Znovu načíst pomocníky - přepínače", + "input_number": "Znovu načíst pomocníky - čísla", "input_select": "Znovu načíst pomocníky - výběry", "input_text": "Znovu načíst pomocníky - texty", "introduction": "Některé části Home Assistant lze načíst bez nutnosti restartování. Volba načtení zahodí jejich aktuální konfiguraci a načte novou.", diff --git a/translations/frontend/el.json b/translations/frontend/el.json index 10dd95d0cf..e2d9b9b2d6 100644 --- a/translations/frontend/el.json +++ b/translations/frontend/el.json @@ -658,7 +658,7 @@ }, "zha_device_info": { "buttons": { - "add": "Προσθήκη συσκευών", + "add": "Προσθήκη συσκευών μέσω αυτής της συσκευής", "clusters": "Διαχείριση συμπλεγμάτων", "reconfigure": "Ρυθμίστε Ξανά Τη Συσκευή", "remove": "Κατάργηση συσκευής", @@ -679,7 +679,7 @@ "unknown": "Άγνωστη", "zha_device_card": { "area_picker_label": "Περιοχή", - "device_name_placeholder": "Όνομα δοσμένο από τον χρήστη", + "device_name_placeholder": "Αλλαγή ονόματος συσκευής", "update_name_button": "Ενημέρωση ονόματος" } } @@ -729,7 +729,7 @@ "confirmation_text": "Όλες οι συσκευές αυτής της περιοχής θα καταστούν μη εκχωρημένες", "confirmation_title": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτή την περιοχή;" }, - "description": "Επισκόπηση όλων των περιοχών στο σπίτι σας.", + "description": "Διαχειριστείτε περιοχές στο σπίτι σας", "editor": { "area_id": "Αναγνωριστικό περιοχής", "create": "Δημιουργία", @@ -1027,7 +1027,7 @@ "cloud": { "account": { "alexa": { - "config_documentation": "Έγγραφα παραμετροποίησης", + "config_documentation": "Τεκμηρίωση παραμετροποίησης", "disable": "Απενεργοποίηση", "enable": "Ενεργοποίηση", "enable_ha_skill": "Ενεργοποιήστε την ικανότητα του Home Assistant για την Alexa", @@ -1489,6 +1489,28 @@ "node_failed": "Ο κόμβος απέτυχε", "stage": "Στάδιο", "zwave_info": "Πληροφορίες Z-Wave" + }, + "node_query_stages": { + "complete": "Η διαδικασία της συνέντευξης ολοκληρώθηκε", + "configuration": "Λήψη τιμών διαμόρφωσης από τον κόμβο", + "dynamic": "Λήψη τιμών που αλλάζουν συχνά από τον κόμβο", + "instances": "Λήψη λεπτομερειών σχετικά με τις παρουσίες ή τα κανάλια που υποστηρίζει μια συσκευή", + "neighbors": "Απόκτηση λίστας των γειτονικών κόμβων", + "probe": "Έλεγχος εάν ο κόμβος είναι ξύπνιος / ενεργός", + "session": "Λήψη σπάνια μεταβαλλόμενων τιμών από τον κόμβο", + "static": "Λήψη στατικών τιμών από τη συσκευή", + "versions": "Λήψη πληροφοριών σχετικά με εκδόσεις υλικολογισμικού και κλάσης εντολών", + "wakeup": "Ρύθμιση υποστήριξης για ουρές αφύπνισης και μηνύματα" + }, + "refresh_node": { + "battery_note": "Εάν ο κόμβος τροφοδοτείται με μπαταρία, φροντίστε να τον ενεργοποιήσετε πριν συνεχίσετε", + "complete": "Ολοκληρώθηκε η ανανέωση κόμβου", + "node_status": "Κατάσταση Κόμβου", + "refreshing_description": "Ανανέωση δεδομένων κόμβου σε εξέλιξη...", + "start_refresh_button": "Εναρξη Ανανέωσης", + "step": "Βήμα", + "title": "Ανανέωση πληροφοριών κόμβου", + "wakeup_header": "Οδηγίες εκκίνησης απο" } }, "person": { @@ -1520,7 +1542,7 @@ "scene": { "activated": "Ενεργοποιημένη σκηνή {name}.", "caption": "Σκηνές", - "description": "Δημιουργία και επεξεργασία σκηνών", + "description": "Διαχείρηση σκηνών", "editor": { "default_name": "Νέα σκηνή", "devices": { @@ -1815,10 +1837,12 @@ }, "node_management": { "add_to_group": "Προσθήκη σε ομάδα", + "exclude_entity": "Εξαίρεση αυτής της οντότητας από τον Home Assistant", "group": "Ομάδα", "header": "Διαχείριση κόμβων Z-Wave", "max_associations": "Μέγιστες ενώσεις:", "node_group_associations": "Κόμβοι συσχετίσεων ομάδων", + "node_protection": "Προστασία κόμβου", "node_to_control": "Κόμβος προς έλεγχο", "nodes_in_group": "Άλλοι κόμβοι σε αυτήν την ομάδα:", "protection": "Προστασία", @@ -2161,7 +2185,7 @@ "header": "Επεξεργασία περιβάλλοντος χρήστη", "menu": { "open": "Ανοίξτε το μενού Lovelace", - "raw_editor": "Επεξεργαστής ρυθμίσεων Raw" + "raw_editor": "Πρόγραμμα επεξεργασίας ρύθμισης παραμέτρων raw" }, "migrate": { "header": "Μη συμβατή διαμόρφωση", @@ -2190,13 +2214,13 @@ "cancel": "Δεν πειράζει", "empty_config": "Ξεκινήστε με μια κενή επισκόπηση", "header": "Πάρτε τον έλεγχο του περιβάλλοντος χρήστη στο Lovelace", - "para": "Από προεπιλογή, το Home Assistant θα διατηρήσει το περιβάλλον χρήστη που έχετε ενημερώνοντας το όταν θα γίνονται διαθέσιμες νέες οντότητες ή στοιχεία Lovelace. Αν πάρετε τον έλεγχο, δεν θα πραγματοποιούμε πλέον αλλαγές για εσάς.", + "para": "Ο πίνακας προεπισκόπησης διαχειρίζεται από το Home Assistant. Αυτό θα ενημερωθεί αυτόματα όταν νέες οντότητες ή στοιχεία διεπαφής Lovelace γίνουν διαθέσιμα. Αν αναλάβετε τον έλεγχο ο πίνακας προεπισκόπισης δεν θα ανανεώνεται αυτόματα. Μπορείτε οποιαδήποτε στιγμή να δημιουργήσετε νέο πίνακα προεπισκόπισης για να πειραματιστείτε", "para_sure": "Είστε βέβαιος ότι θέλετε να πάρετε τον έλεγχο του περιβάλλοντος χρήστη;", "save": "Πάρτε τον έλεγχο", "yaml_mode": "Χρησιμοποιείτε τη λειτουργία YAML για αυτόν τον πίνακα εργαλείων, πράγμα που σημαίνει ότι δεν μπορείτε να αλλάξετε τη διαμόρφωση Lovelace από το περιβάλλον εργασίας χρήστη. Εάν θέλετε να διαχειριστείτε αυτόν τον πίνακα εργαλείων από το περιβάλλον εργασίας χρήστη, καταργήστε το 'mode: yaml' από τη διαμόρφωση Lovelace στο 'configuration.yaml.'." }, "select_view": { - "dashboard_label": "Επισκόπηση", + "dashboard_label": "Πίνακας Επισκόπησης", "header": "Επιλέξτε μια προβολή" }, "suggest_card": { @@ -2426,7 +2450,7 @@ }, "profile": { "advanced_mode": { - "description": "εξειδικευμένη λειτουργία", + "description": "Ξεκλειδώνει προηγμένες δυνατότητες.", "link_promo": "Μάθετε περισσότερα", "title": "Εξειδικευμένη λειτουργία" }, diff --git a/translations/frontend/en.json b/translations/frontend/en.json index 7abcf52ea9..461f4c7471 100644 --- a/translations/frontend/en.json +++ b/translations/frontend/en.json @@ -554,6 +554,10 @@ "loading_history": "Loading state history...", "no_history_found": "No state history found." }, + "picture-upload": { + "label": "Picture", + "unsupported_format": "Unsupported format, please choose a JPEG, PNG or GIF image." + }, "related-items": { "area": "Area", "automation": "Part of the following automations", @@ -656,6 +660,9 @@ "required_error_msg": "This field is required", "yaml_not_editable": "The settings of this entity cannot be edited from the UI. Only entities set up from the UI are configurable from the UI." }, + "image_cropper": { + "crop": "Crop" + }, "more_info_control": { "dismiss": "Dismiss dialog", "edit": "Edit entity", diff --git a/translations/frontend/lb.json b/translations/frontend/lb.json index 91c2754fc2..c2f3ef2afc 100644 --- a/translations/frontend/lb.json +++ b/translations/frontend/lb.json @@ -1649,25 +1649,41 @@ "ozw": { "common": { "node_id": "Node ID", + "ozw_instance": "OpenZWave Instanz", "zwave": "Z-Wave" }, + "device_info": { + "node_failed": "Feeler am Node", + "stage": "Stage", + "zwave_info": "Z-Wave Info" + }, "node_query_stages": { + "associations": "Associatiounsgruppen a Memberen aktualiséieren", "complete": "Interview Prozess ass komplett", "configuration": "Konfiguratiounswerter vum Node kréien", "instances": "Detailer kréien iwwert wéieng Instanzen oder Kanäl en Apparat ënnerstëtzt", + "manufacturerspecific1": "Hiersteller a Produkt ID Code vum Node kréien", "manufacturerspecific2": "Zousätzlech Hiersteller a Produkt ID Coden vum Node kréien", "neighbors": "Eng Lëscht vun den Nopere vum Node kréien", + "nodeinfo": "Kommando Klassen vum Node kréien", + "nodeplusinfo": "Z-Wave+ Informatiounen vum Node kréien", + "probe": "Checken op de Node un ass", + "protocolinfo": "Basis Z-Wave Fäegkeeten fir dësem Node vum Kontroller kréien", "static": "Statesch Wäerter vum Apparat kréien", - "versions": "Informatioun kréien iwwert Firmware a Kommando Klass Versiounen" + "versions": "Informatioun kréien iwwert Firmware a Kommando Klass Versiounen", + "wakeup": "Ënnerstëtzung fir Erwäche Waardeschlaangen an Noriichten astellen" }, "refresh_node": { + "battery_note": "Falls den Node Batterie bedriwwen ass, stell sécher fir en z'erwächen iers de weiderfiers", "complete": "Aktualiséierung vun den Node Informatioune komplett", + "description": "Dëst befeelt OpenZWave fir en Node ofzefroen a Kommando Klassen, Fäegkeeten a Wäerter vum Node aktualiséieren.", "node_status": "Status vum Node", "refreshing_description": "Node Informatiounen aktualiséieren...", "start_refresh_button": "Aktualiséierung starten", "step": "Schrëtt", "title": "Node Informatiounen aktualiséieren", - "wakeup_header": "Instruktioune fir d'erwäche vun" + "wakeup_header": "Instruktioune fir d'erwäche vun", + "wakeup_instructions_source": "D'Instruktioune fir d'erwäche si vun der OpenZwave Communautéit Datebank." } }, "person": { diff --git a/translations/frontend/zh-Hant.json b/translations/frontend/zh-Hant.json index adc72e651f..300057102a 100644 --- a/translations/frontend/zh-Hant.json +++ b/translations/frontend/zh-Hant.json @@ -1656,6 +1656,37 @@ "node_failed": "節點失敗", "stage": "階段", "zwave_info": "Z-Wave 資訊" + }, + "node_query_stages": { + "associations": "更新相關群組與成員", + "cacheload": "由 OpenZwave 暫存檔載入資訊。電池供電節點將會保持此階段直到節點喚醒。", + "complete": "探訪過程完成", + "configuration": "由節點獲得設定值", + "dynamic": "由節點獲得頻率變更值", + "instances": "獲得設備或頻道支援的詳細資料", + "manufacturerspecific1": "由節點獲得製造廠商與產品 ID 代碼", + "manufacturerspecific2": "由節點獲得附加製造商與產品 ID 代碼", + "neighbors": "獲得節點週邊設備列表", + "nodeinfo": "由節點獲得支援命令 Class", + "nodeplusinfo": "由節點獲得 Z-Wave+ 資訊", + "probe": "檢查節點是否為喚醒狀態", + "protocolinfo": "由控制器獲得此節點基本 Z-Wave 相容性資訊", + "session": "由節點獲得非頻率變更值", + "static": "由設備獲得靜態值", + "versions": "獲得韌體與命令 Class 版本資訊", + "wakeup": "設定喚醒序列與訊息之支援" + }, + "refresh_node": { + "battery_note": "假如節點為電池供電、請確定先行喚醒以繼續", + "complete": "節點更新完成", + "description": "將會通知 OpenZWave 重新探訪節點並更新節點命令 Class、相容性與數值。", + "node_status": "節點狀態", + "refreshing_description": "正在更新節點資訊...", + "start_refresh_button": "開始更新", + "step": "階段", + "title": "更新節點資訊", + "wakeup_header": "喚醒說明", + "wakeup_instructions_source": "喚醒說明為來自 OpenZWave 社群的設備資料庫。" } }, "person": { From d7e409b042d1823a303f6271e23c99155c87f55d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 20 Aug 2020 15:34:52 +0200 Subject: [PATCH 37/38] Add tag config panel (#6601) Co-authored-by: Bram Kragten --- src/data/automation.ts | 7 + src/data/tag.ts | 57 ++++ src/external_app/external_config.ts | 1 + .../trigger/ha-automation-trigger-row.ts | 2 + .../types/ha-automation-trigger-tag.ts | 72 +++++ src/panels/config/ha-panel-config.ts | 17 + src/panels/config/tags/dialog-tag-detail.ts | 209 +++++++++++++ src/panels/config/tags/ha-config-tags.ts | 293 ++++++++++++++++++ .../config/tags/show-dialog-tag-detail.ts | 27 ++ src/panels/config/tags/tag-image.ts | 93 ++++++ src/translations/en.json | 34 +- 11 files changed, 809 insertions(+), 3 deletions(-) create mode 100644 src/data/tag.ts create mode 100644 src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts create mode 100644 src/panels/config/tags/dialog-tag-detail.ts create mode 100644 src/panels/config/tags/ha-config-tags.ts create mode 100644 src/panels/config/tags/show-dialog-tag-detail.ts create mode 100644 src/panels/config/tags/tag-image.ts diff --git a/src/data/automation.ts b/src/data/automation.ts index b3e8d0b0f8..d4eaa843c7 100644 --- a/src/data/automation.ts +++ b/src/data/automation.ts @@ -90,6 +90,12 @@ export interface ZoneTrigger { event: "enter" | "leave"; } +export interface TagTrigger { + platform: "tag"; + tag_id: string; + device_id?: string; +} + export interface TimeTrigger { platform: "time"; at: string; @@ -116,6 +122,7 @@ export type Trigger = | TimePatternTrigger | WebhookTrigger | ZoneTrigger + | TagTrigger | TimeTrigger | TemplateTrigger | EventTrigger diff --git a/src/data/tag.ts b/src/data/tag.ts new file mode 100644 index 0000000000..870777f7cb --- /dev/null +++ b/src/data/tag.ts @@ -0,0 +1,57 @@ +import { HomeAssistant } from "../types"; +import { HassEventBase } from "home-assistant-js-websocket"; + +export const EVENT_TAG_SCANNED = "tag_scanned"; + +export interface TagScannedEvent extends HassEventBase { + event_type: "tag_scanned"; + data: { + tag_id: string; + device_id?: string; + }; +} + +export interface Tag { + id: string; + name?: string; + description?: string; + last_scanned?: string; +} + +export interface UpdateTagParams { + name?: Tag["name"]; + description?: Tag["description"]; +} + +export const fetchTags = async (hass: HomeAssistant) => + hass.callWS({ + type: "tag/list", + }); + +export const createTag = async ( + hass: HomeAssistant, + params: UpdateTagParams, + tagId?: string +) => + hass.callWS({ + type: "tag/create", + tag_id: tagId, + ...params, + }); + +export const updateTag = async ( + hass: HomeAssistant, + tagId: string, + params: UpdateTagParams +) => + hass.callWS({ + ...params, + type: "tag/update", + tag_id: tagId, + }); + +export const deleteTag = async (hass: HomeAssistant, tagId: string) => + hass.callWS({ + type: "tag/delete", + tag_id: tagId, + }); diff --git a/src/external_app/external_config.ts b/src/external_app/external_config.ts index 7651b1307b..d911ea2593 100644 --- a/src/external_app/external_config.ts +++ b/src/external_app/external_config.ts @@ -2,6 +2,7 @@ import { ExternalMessaging } from "./external_messaging"; export interface ExternalConfig { hasSettingsScreen: boolean; + canWriteTag: boolean; } export const getExternalConfig = ( diff --git a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts index c88c644683..a50373bbc8 100644 --- a/src/panels/config/automation/trigger/ha-automation-trigger-row.ts +++ b/src/panels/config/automation/trigger/ha-automation-trigger-row.ts @@ -34,6 +34,7 @@ import "./types/ha-automation-trigger-time"; import "./types/ha-automation-trigger-time_pattern"; import "./types/ha-automation-trigger-webhook"; import "./types/ha-automation-trigger-zone"; +import "./types/ha-automation-trigger-tag"; import { ActionDetail } from "@material/mwc-list/mwc-list-foundation"; import { haStyle } from "../../../../resources/styles"; @@ -46,6 +47,7 @@ const OPTIONS = [ "mqtt", "numeric_state", "sun", + "tag", "template", "time", "time_pattern", diff --git a/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts b/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts new file mode 100644 index 0000000000..954e1ef144 --- /dev/null +++ b/src/panels/config/automation/trigger/types/ha-automation-trigger-tag.ts @@ -0,0 +1,72 @@ +import "@polymer/paper-input/paper-input"; +import { + customElement, + html, + LitElement, + property, + internalProperty, + PropertyValues, +} from "lit-element"; +import { TagTrigger } from "../../../../../data/automation"; +import { HomeAssistant } from "../../../../../types"; +import { TriggerElement } from "../ha-automation-trigger-row"; +import { Tag, fetchTags } from "../../../../../data/tag"; +import { fireEvent } from "../../../../../common/dom/fire_event"; + +@customElement("ha-automation-trigger-tag") +export class HaTagTrigger extends LitElement implements TriggerElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public trigger!: TagTrigger; + + @internalProperty() private _tags: Tag[] = []; + + public static get defaultConfig() { + return { tag_id: "" }; + } + + protected firstUpdated(changedProperties: PropertyValues) { + super.firstUpdated(changedProperties); + this._fetchTags(); + } + + protected render() { + const { tag_id } = this.trigger; + return html` + + + ${this._tags.map( + (tag) => html` + + ${tag.name || tag.id} + + ` + )} + + + `; + } + + private async _fetchTags() { + this._tags = await fetchTags(this.hass); + } + + private _tagChanged(ev) { + fireEvent(this, "value-changed", { + value: { + ...this.trigger, + tag_id: ev.detail.item.tag.id, + }, + }); + } +} diff --git a/src/panels/config/ha-panel-config.ts b/src/panels/config/ha-panel-config.ts index 649e6168ae..dad0e22ee4 100644 --- a/src/panels/config/ha-panel-config.ts +++ b/src/panels/config/ha-panel-config.ts @@ -32,6 +32,7 @@ import { mdiInformation, mdiMathLog, mdiPencil, + mdiNfcVariant, } from "@mdi/js"; declare global { @@ -99,6 +100,15 @@ export const configSections: { [name: string]: PageNavigation[] } = { core: true, }, ], + experimental: [ + { + component: "tags", + path: "/config/tags", + translationKey: "ui.panel.config.tags.caption", + iconPath: mdiNfcVariant, + core: true, + }, + ], lovelace: [ { component: "lovelace", @@ -195,6 +205,13 @@ class HaPanelConfig extends HassRouterPage { /* webpackChunkName: "panel-config-automation" */ "./automation/ha-config-automation" ), }, + tags: { + tag: "ha-config-tags", + load: () => + import( + /* webpackChunkName: "panel-config-tags" */ "./tags/ha-config-tags" + ), + }, cloud: { tag: "ha-config-cloud", load: () => diff --git a/src/panels/config/tags/dialog-tag-detail.ts b/src/panels/config/tags/dialog-tag-detail.ts new file mode 100644 index 0000000000..f4edecf711 --- /dev/null +++ b/src/panels/config/tags/dialog-tag-detail.ts @@ -0,0 +1,209 @@ +import "@material/mwc-button"; +import "@polymer/paper-input/paper-input"; +import { + css, + CSSResult, + html, + LitElement, + property, + internalProperty, + TemplateResult, + customElement, +} from "lit-element"; +import { fireEvent } from "../../../common/dom/fire_event"; +import { createCloseHeading } from "../../../components/ha-dialog"; +import "../../../components/ha-switch"; +import "../../../components/ha-formfield"; +import "../../../components/map/ha-location-editor"; +import { haStyleDialog } from "../../../resources/styles"; +import { HomeAssistant } from "../../../types"; +import { HassDialog } from "../../../dialogs/make-dialog-manager"; +import { TagDetailDialogParams } from "./show-dialog-tag-detail"; +import { UpdateTagParams, Tag } from "../../../data/tag"; + +@customElement("dialog-tag-detail") +class DialogTagDetail extends LitElement implements HassDialog { + @property({ attribute: false }) public hass!: HomeAssistant; + + @internalProperty() private _id?: string; + + @internalProperty() private _name!: string; + + @internalProperty() private _error?: string; + + @internalProperty() private _params?: TagDetailDialogParams; + + @internalProperty() private _submitting = false; + + public showDialog(params: TagDetailDialogParams): void { + this._params = params; + this._error = undefined; + if (this._params.entry) { + this._name = this._params.entry.name || ""; + } else { + this._id = ""; + this._name = ""; + } + } + + public closeDialog(): void { + this._params = undefined; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + + protected render(): TemplateResult { + if (!this._params) { + return html``; + } + + return html` + +
+ ${this._error ? html`
${this._error}
` : ""} +
+ ${this._params.entry + ? html`${this.hass!.localize( + "ui.panel.config.tags.detail.tag_id" + )}: + ${this._params.entry.id}` + : ""} + + ${!this._params.entry + ? html` ` + : ""} +
+
+ ${this._params.entry + ? html` + + ${this.hass!.localize("ui.panel.config.tags.detail.delete")} + + ` + : html``} + + ${this._params.entry + ? this.hass!.localize("ui.panel.config.tags.detail.update") + : this.hass!.localize("ui.panel.config.tags.detail.create")} + + ${this._params.openWrite && !this._params.entry + ? html` + ${this.hass!.localize( + "ui.panel.config.tags.detail.create_and_write" + )} + ` + : ""} +
+ `; + } + + private _valueChanged(ev: CustomEvent) { + const configValue = (ev.target as any).configValue; + + this._error = undefined; + this[`_${configValue}`] = ev.detail.value; + } + + private async _updateEntry() { + this._submitting = true; + let newValue: Tag | undefined; + try { + const values: UpdateTagParams = { + name: this._name.trim(), + }; + if (this._params!.entry) { + newValue = await this._params!.updateEntry!(values); + } else { + newValue = await this._params!.createEntry(values, this._id); + } + this._params = undefined; + } catch (err) { + this._error = err ? err.message : "Unknown error"; + } finally { + this._submitting = false; + } + return newValue; + } + + private async _updateWriteEntry() { + const tag = await this._updateEntry(); + if (!tag) { + return; + } + this._params?.openWrite!(tag); + } + + private async _deleteEntry() { + this._submitting = true; + try { + if (await this._params!.removeEntry!()) { + this._params = undefined; + } + } finally { + this._submitting = false; + } + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + a { + color: var(--primary-color); + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-tag-detail": DialogTagDetail; + } +} diff --git a/src/panels/config/tags/ha-config-tags.ts b/src/panels/config/tags/ha-config-tags.ts new file mode 100644 index 0000000000..8abdc49d13 --- /dev/null +++ b/src/panels/config/tags/ha-config-tags.ts @@ -0,0 +1,293 @@ +import "@material/mwc-fab"; +import { mdiCog, mdiContentDuplicate, mdiPlus, mdiRobot } from "@mdi/js"; +import { + customElement, + html, + internalProperty, + LitElement, + property, + PropertyValues, +} from "lit-element"; +import memoizeOne from "memoize-one"; +import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table"; +import "../../../components/ha-card"; +import "../../../components/ha-relative-time"; +import { + createTag, + deleteTag, + EVENT_TAG_SCANNED, + fetchTags, + Tag, + TagScannedEvent, + updateTag, + UpdateTagParams, +} from "../../../data/tag"; +import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; +import "../../../layouts/hass-tabs-subpage-data-table"; +import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; +import { HomeAssistant, Route } from "../../../types"; +import { configSections } from "../ha-panel-config"; +import { showTagDetailDialog } from "./show-dialog-tag-detail"; +import "./tag-image"; +import { getExternalConfig } from "../../../external_app/external_config"; +import { showAutomationEditor, TagTrigger } from "../../../data/automation"; + +export interface TagRowData extends Tag { + last_scanned_datetime: Date | null; +} + +@customElement("ha-config-tags") +export class HaConfigTags extends SubscribeMixin(LitElement) { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public isWide!: boolean; + + @property() public narrow!: boolean; + + @property() public route!: Route; + + @internalProperty() private _tags: Tag[] = []; + + @internalProperty() private _canWriteTags = false; + + private _columns = memoizeOne( + ( + narrow: boolean, + canWriteTags: boolean, + _language + ): DataTableColumnContainer => { + const columns: DataTableColumnContainer = { + icon: { + title: "", + type: "icon", + template: (_icon, tag) => html``, + }, + display_name: { + title: this.hass.localize("ui.panel.config.tags.headers.name"), + sortable: true, + filterable: true, + grows: true, + template: (name, tag: any) => html`${name} + ${narrow + ? html`
+ ${tag.last_scanned + ? html`` + : this.hass.localize("ui.components.relative_time.never")} +
` + : ""}`, + }, + }; + if (!narrow) { + columns.last_scanned_datetime = { + title: this.hass.localize( + "ui.panel.config.tags.headers.last_scanned" + ), + sortable: true, + direction: "desc", + width: "20%", + template: (last_scanned_datetime) => html` + ${last_scanned_datetime + ? html`` + : this.hass.localize("ui.components.relative_time.never")} + `, + }; + } + if (canWriteTags) { + columns.write = { + title: "", + type: "icon-button", + template: (_write, tag: any) => html` + this._openWrite((ev.currentTarget as any).tag)} + title=${this.hass.localize("ui.panel.config.tags.write")} + > + + `, + }; + } + columns.automation = { + title: "", + type: "icon-button", + template: (_automation, tag: any) => html` + this._createAutomation((ev.currentTarget as any).tag)} + title=${this.hass.localize("ui.panel.config.tags.create_automation")} + > + + `, + }; + columns.edit = { + title: "", + type: "icon-button", + template: (_settings, tag: any) => html` + this._openDialog((ev.currentTarget as any).tag)} + title=${this.hass.localize("ui.panel.config.tags.edit")} + > + + `, + }; + return columns; + } + ); + + private _data = memoizeOne((tags: Tag[]): TagRowData[] => { + return tags.map((tag) => { + return { + ...tag, + display_name: tag.name || tag.id, + last_scanned_datetime: tag.last_scanned + ? new Date(tag.last_scanned) + : null, + }; + }); + }); + + protected firstUpdated(changedProperties: PropertyValues) { + super.firstUpdated(changedProperties); + this._fetchTags(); + if (this.hass && this.hass.auth.external) { + getExternalConfig(this.hass.auth.external).then((conf) => { + this._canWriteTags = conf.canWriteTag; + }); + } + } + + protected hassSubscribe() { + return [ + this.hass.connection.subscribeEvents((ev) => { + const foundTag = this._tags.find((tag) => tag.id === ev.data.tag_id); + if (!foundTag) { + this._fetchTags(); + return; + } + foundTag.last_scanned = ev.time_fired; + this._tags = [...this._tags]; + }, EVENT_TAG_SCANNED), + ]; + } + + protected render() { + return html` + + + + + + `; + } + + private async _fetchTags() { + this._tags = await fetchTags(this.hass); + } + + private _openWrite(tag: Tag) { + this.hass.auth.external!.fireMessage({ + type: "tag/write", + payload: { name: tag.name || null, tag: tag.id }, + }); + } + + private _createAutomation(tag: Tag) { + const data = { + alias: this.hass.localize( + "ui.panel.config.tags.automation_title", + "name", + tag.name || tag.id + ), + trigger: [{ platform: "tag", tag_id: tag.id } as TagTrigger], + }; + showAutomationEditor(this, data); + } + + private _addTag() { + this._openDialog(); + } + + private _openDialog(entry?: Tag) { + showTagDetailDialog(this, { + entry, + openWrite: this._canWriteTags ? (tag) => this._openWrite(tag) : undefined, + createEntry: (values, tagId) => this._createTag(values, tagId), + updateEntry: entry + ? (values) => this._updateTag(entry, values) + : undefined, + removeEntry: entry ? () => this._removeTag(entry) : undefined, + }); + } + + private async _createTag( + values: Partial, + tagId?: string + ): Promise { + const newTag = await createTag(this.hass, values, tagId); + this._tags = [...this._tags, newTag]; + return newTag; + } + + private async _updateTag( + selectedTag: Tag, + values: Partial + ): Promise { + const updated = await updateTag(this.hass, selectedTag.id, values); + this._tags = this._tags.map((tag) => + tag.id === selectedTag.id ? updated : tag + ); + return updated; + } + + private async _removeTag(selectedTag: Tag) { + if ( + !(await showConfirmationDialog(this, { + title: "Remove tag?", + text: `Are you sure you want to remove tag ${ + selectedTag.name || selectedTag.id + }?`, + dismissText: this.hass!.localize("ui.common.no"), + confirmText: this.hass!.localize("ui.common.yes"), + })) + ) { + return false; + } + try { + await deleteTag(this.hass, selectedTag.id); + this._tags = this._tags.filter((tag) => tag.id !== selectedTag.id); + return true; + } catch (err) { + return false; + } + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-config-tags": HaConfigTags; + } +} diff --git a/src/panels/config/tags/show-dialog-tag-detail.ts b/src/panels/config/tags/show-dialog-tag-detail.ts new file mode 100644 index 0000000000..1088a0778c --- /dev/null +++ b/src/panels/config/tags/show-dialog-tag-detail.ts @@ -0,0 +1,27 @@ +import { fireEvent } from "../../../common/dom/fire_event"; +import { Tag, UpdateTagParams } from "../../../data/tag"; + +export interface TagDetailDialogParams { + entry?: Tag; + openWrite?: (tag: Tag) => void; + createEntry: ( + values: Partial, + tagId?: string + ) => Promise; + updateEntry?: (updates: Partial) => Promise; + removeEntry?: () => Promise; +} + +export const loadTagDetailDialog = () => + import(/* webpackChunkName: "dialog-tag-detail" */ "./dialog-tag-detail"); + +export const showTagDetailDialog = ( + element: HTMLElement, + systemLogDetailParams: TagDetailDialogParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-tag-detail", + dialogImport: loadTagDetailDialog, + dialogParams: systemLogDetailParams, + }); +}; diff --git a/src/panels/config/tags/tag-image.ts b/src/panels/config/tags/tag-image.ts new file mode 100644 index 0000000000..c1b10ca86c --- /dev/null +++ b/src/panels/config/tags/tag-image.ts @@ -0,0 +1,93 @@ +import { + property, + customElement, + LitElement, + html, + CSSResult, + css, +} from "lit-element"; +import "../../../components/ha-svg-icon"; +import { mdiNfcVariant } from "@mdi/js"; +import { TagRowData } from "./ha-config-tags"; + +@customElement("tag-image") +export class HaTagImage extends LitElement { + @property() public tag?: TagRowData; + + private _timeout?: number; + + protected updated() { + const msSinceLastScaned = this.tag?.last_scanned_datetime + ? new Date().getTime() - this.tag.last_scanned_datetime.getTime() + : undefined; + + if (msSinceLastScaned && msSinceLastScaned < 1000) { + if (this._timeout) { + clearTimeout(this._timeout); + this._timeout = undefined; + this.classList.remove("just-scanned"); + requestAnimationFrame(() => this.classList.add("just-scanned")); + } else { + this.classList.add("just-scanned"); + } + this._timeout = window.setTimeout(() => { + this.classList.remove("just-scanned"); + this._timeout = undefined; + }, 10000); + } else if (!msSinceLastScaned || msSinceLastScaned > 10000) { + clearTimeout(this._timeout); + this._timeout = undefined; + this.classList.remove("just-scanned"); + } + } + + protected render() { + if (!this.tag) { + return html``; + } + return html`
+
+ +
+
`; + } + + static get styles(): CSSResult { + return css` + .image { + height: 100%; + width: 100%; + background-size: cover; + border-radius: 50%; + display: flex; + justify-content: center; + align-items: center; + } + .container { + height: 40px; + width: 40px; + border-radius: 50%; + } + :host(.just-scanned) .container { + animation: glow 10s; + } + @keyframes glow { + 0% { + box-shadow: 0px 0px 24px 0px rgba(var(--rgb-primary-color), 0); + } + 10% { + box-shadow: 0px 0px 24px 0px rgba(var(--rgb-primary-color), 1); + } + 100% { + box-shadow: 0px 0px 24px 0px rgba(var(--rgb-primary-color), 0); + } + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "tag-image": HaTagImage; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index cf43d60daa..6630adb0e6 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -601,6 +601,31 @@ "confirmation_text": "All devices in this area will become unassigned." } }, + "tags": { + "caption": "Tags", + "description": "Manage tags", + "no_tags": "No tags", + "add_tag": "Add tag", + "write": "Write", + "edit": "Edit", + "create_automation": "Create automation with tag", + "automation_title": "Tag {name} is scanned", + "headers": { + "name": "Name", + "last_scanned": "Last scanned" + }, + "detail": { + "new_tag": "New tag", + "name": "Name", + "description": "Description", + "tag_id": "Tag id", + "tag_id_placeholder": "Autogenerated when left empty", + "delete": "Delete", + "update": "Update", + "create": "Create", + "create_and_write": "Create and Write" + } + }, "helpers": { "caption": "Helpers", "description": "Manage elements that help build automations", @@ -878,7 +903,7 @@ "duplicate": "Duplicate", "delete": "[%key:ui::panel::mailbox::delete_button%]", "delete_confirm": "Are you sure you want to delete this?", - "unsupported_platform": "Unsupported platform: {platform}", + "unsupported_platform": "No UI support for platform: {platform}", "type_select": "Trigger type", "type": { "device": { @@ -933,6 +958,9 @@ "sunset": "Sunset", "offset": "Offset (optional)" }, + "tag": { + "label": "Tag" + }, "template": { "label": "Template", "value_template": "Value template" @@ -970,7 +998,7 @@ "duplicate": "[%key:ui::panel::config::automation::editor::triggers::duplicate%]", "delete": "[%key:ui::panel::mailbox::delete_button%]", "delete_confirm": "[%key:ui::panel::config::automation::editor::triggers::delete_confirm%]", - "unsupported_condition": "Unsupported condition: {condition}", + "unsupported_condition": "No UI support for condition: {condition}", "type_select": "Condition type", "type": { "and": { @@ -1035,7 +1063,7 @@ "duplicate": "[%key:ui::panel::config::automation::editor::triggers::duplicate%]", "delete": "[%key:ui::panel::mailbox::delete_button%]", "delete_confirm": "[%key:ui::panel::config::automation::editor::triggers::delete_confirm%]", - "unsupported_action": "Unsupported action: {action}", + "unsupported_action": "No UI support for action: {action}", "type_select": "Action type", "type": { "service": { From 3367fadc3a714191a71e034de2f342062d8a3d9d Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Thu, 20 Aug 2020 15:52:06 +0200 Subject: [PATCH 38/38] Bumped version to 20200820.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 289a8db76f..2c255baf5d 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20200811.0", + version="20200820.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors",