diff --git a/gallery/src/demos/demo-integration-card.ts b/gallery/src/demos/demo-integration-card.ts
index 1e23303bc4..97e581f2cc 100644
--- a/gallery/src/demos/demo-integration-card.ts
+++ b/gallery/src/demos/demo-integration-card.ts
@@ -28,10 +28,13 @@ const createConfigEntry = (
title,
source: "zeroconf",
state: "loaded",
- connection_class: "local_push",
supports_options: false,
supports_unload: true,
disabled_by: null,
+ system_options: {
+ disable_new_entities: false,
+ disable_polling: false,
+ },
reason: null,
...override,
});
@@ -64,6 +67,12 @@ const configPanelEntry = createConfigEntry("Config Panel", {
const optionsFlowEntry = createConfigEntry("Options Flow", {
supports_options: true,
});
+const disabledPollingEntry = createConfigEntry("Disabled Polling", {
+ system_options: {
+ disable_new_entities: false,
+ disable_polling: true,
+ },
+});
const setupErrorEntry = createConfigEntry("Setup Error", {
state: "setup_error",
});
@@ -136,6 +145,7 @@ const configEntries: Array<{
{ items: [loadedEntry] },
{ items: [configPanelEntry] },
{ items: [optionsFlowEntry] },
+ { items: [disabledPollingEntry] },
{ items: [nameAsDomainEntry] },
{ items: [longNameEntry] },
{ items: [longNonBreakingNameEntry] },
diff --git a/setup.py b/setup.py
index acc46ddd38..e5030abd42 100644
--- a/setup.py
+++ b/setup.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
- version="20210531.0",
+ version="20210531.1",
description="The Home Assistant frontend",
url="https://github.com/home-assistant/home-assistant-polymer",
author="The Home Assistant Authors",
diff --git a/src/components/ha-network.ts b/src/components/ha-network.ts
index a4163ae720..451e709176 100644
--- a/src/components/ha-network.ts
+++ b/src/components/ha-network.ts
@@ -1,5 +1,12 @@
import "@polymer/paper-tooltip/paper-tooltip";
-import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
+import {
+ css,
+ CSSResultGroup,
+ html,
+ nothing,
+ LitElement,
+ TemplateResult,
+} from "lit";
import { customElement, state, property } from "lit/decorators";
import {
Adapter,
@@ -17,18 +24,19 @@ import "./ha-icon";
const format_addresses = (
addresses: IPv6ConfiguredAddress[] | IPv4ConfiguredAddress[]
-): TemplateResult[] =>
- addresses.map(
- (address) => html`${address.address}/${address.network_prefix}`
- );
+): TemplateResult =>
+ html`${addresses.map((address, i) => [
+ html`${address.address}/${address.network_prefix}`,
+ i < addresses.length - 1 ? ", " : nothing,
+ ])}`;
const format_auto_detected_interfaces = (
adapters: Adapter[]
): Array =>
adapters.map((adapter) =>
adapter.auto
- ? html`${adapter.name} (${format_addresses(adapter.ipv4)}
- ${format_addresses(adapter.ipv6)} )`
+ ? html`${adapter.name}
+ (${format_addresses([...adapter.ipv4, ...adapter.ipv6])})`
: ""
);
@@ -88,8 +96,7 @@ export class HaNetwork extends LitElement {
: ""}
- ${format_addresses(adapter.ipv4)}
- ${format_addresses(adapter.ipv6)}
+ ${format_addresses([...adapter.ipv4, ...adapter.ipv6])}
`
)
diff --git a/src/data/config_entries.ts b/src/data/config_entries.ts
index 9bb203c942..8e4de41a9e 100644
--- a/src/data/config_entries.ts
+++ b/src/data/config_entries.ts
@@ -12,9 +12,9 @@ export interface ConfigEntry {
| "setup_retry"
| "not_loaded"
| "failed_unload";
- connection_class: string;
supports_options: boolean;
supports_unload: boolean;
+ system_options: ConfigEntrySystemOptions;
disabled_by: "user" | null;
reason: string | null;
}
@@ -25,6 +25,7 @@ export interface ConfigEntryMutableParams {
export interface ConfigEntrySystemOptions {
disable_new_entities: boolean;
+ disable_polling: boolean;
}
export const getConfigEntries = (hass: HomeAssistant) =>
@@ -72,21 +73,15 @@ export const enableConfigEntry = (hass: HomeAssistant, configEntryId: string) =>
disabled_by: null,
});
-export const getConfigEntrySystemOptions = (
- hass: HomeAssistant,
- configEntryId: string
-) =>
- hass.callWS({
- type: "config_entries/system_options/list",
- entry_id: configEntryId,
- });
-
export const updateConfigEntrySystemOptions = (
hass: HomeAssistant,
configEntryId: string,
params: Partial
) =>
- hass.callWS({
+ hass.callWS<{
+ require_restart: boolean;
+ system_options: ConfigEntrySystemOptions;
+ }>({
type: "config_entries/system_options/update",
entry_id: configEntryId,
...params,
diff --git a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts
index bd1f6bbcd1..92cac06fef 100644
--- a/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts
+++ b/src/dialogs/config-entry-system-options/dialog-config-entry-system-options.ts
@@ -3,17 +3,14 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
import { computeRTLDirection } from "../../common/util/compute_rtl";
-import "../../components/ha-circular-progress";
import "../../components/ha-dialog";
import "../../components/ha-formfield";
import "../../components/ha-switch";
import type { HaSwitch } from "../../components/ha-switch";
-import {
- getConfigEntrySystemOptions,
- updateConfigEntrySystemOptions,
-} from "../../data/config_entries";
+import { updateConfigEntrySystemOptions } from "../../data/config_entries";
import { haStyleDialog } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
+import { showAlertDialog } from "../generic/show-dialog-box";
import { ConfigEntrySystemOptionsDialogParams } from "./show-dialog-config-entry-system-options";
@customElement("dialog-config-entry-system-options")
@@ -22,12 +19,12 @@ class DialogConfigEntrySystemOptions extends LitElement {
@state() private _disableNewEntities!: boolean;
+ @state() private _disablePolling!: boolean;
+
@state() private _error?: string;
@state() private _params?: ConfigEntrySystemOptionsDialogParams;
- @state() private _loading = false;
-
@state() private _submitting = false;
public async showDialog(
@@ -35,13 +32,8 @@ class DialogConfigEntrySystemOptions extends LitElement {
): Promise {
this._params = params;
this._error = undefined;
- this._loading = true;
- const systemOptions = await getConfigEntrySystemOptions(
- this.hass,
- params.entry.entry_id
- );
- this._loading = false;
- this._disableNewEntities = systemOptions.disable_new_entities;
+ this._disableNewEntities = params.entry.system_options.disable_new_entities;
+ this._disablePolling = params.entry.system_options.disable_polling;
}
public closeDialog(): void {
@@ -66,45 +58,57 @@ class DialogConfigEntrySystemOptions extends LitElement {
this._params.entry.domain
)}
>
-
- ${this._loading
- ? html`
-
-
-
- `
- : html`
- ${this._error
- ? html`
${this._error}
`
- : ""}
-
- `}
-
+ ${this._error ? html` ${this._error}
` : ""}
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_new_entities_label"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_new_entities_description",
+ "integration",
+ this.hass.localize(
+ `component.${this._params.entry.domain}.title`
+ ) || this._params.entry.domain
+ )}
+
`}
+ .dir=${computeRTLDirection(this.hass)}
+ >
+
+
+ ${this._allowUpdatePolling()
+ ? html`
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_polling_label"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.dialogs.config_entry_system_options.enable_polling_description",
+ "integration",
+ this.hass.localize(
+ `component.${this._params.entry.domain}.title`
+ ) || this._params.entry.domain
+ )}
+
`}
+ .dir=${computeRTLDirection(this.hass)}
+ >
+
+
+ `
+ : ""}
${this.hass.localize("ui.dialogs.config_entry_system_options.update")}
@@ -123,21 +127,53 @@ class DialogConfigEntrySystemOptions extends LitElement {
`;
}
+ private _allowUpdatePolling() {
+ return (
+ this._params!.manifest &&
+ (this._params!.manifest.iot_class === "local_polling" ||
+ this._params!.manifest.iot_class === "cloud_polling")
+ );
+ }
+
private _disableNewEntitiesChanged(ev: Event): void {
this._error = undefined;
this._disableNewEntities = !(ev.target as HaSwitch).checked;
}
+ private _disablePollingChanged(ev: Event): void {
+ this._error = undefined;
+ this._disablePolling = !(ev.target as HaSwitch).checked;
+ }
+
private async _updateEntry(): Promise {
this._submitting = true;
+ const data: Parameters[2] = {
+ disable_new_entities: this._disableNewEntities,
+ };
+ if (this._allowUpdatePolling()) {
+ data.disable_polling = this._disablePolling;
+ }
try {
- await updateConfigEntrySystemOptions(
+ const result = await updateConfigEntrySystemOptions(
this.hass,
this._params!.entry.entry_id,
- {
- disable_new_entities: this._disableNewEntities,
- }
+ data
);
+ if (result.require_restart) {
+ await showAlertDialog(this, {
+ text: this.hass.localize(
+ "ui.dialogs.config_entry_system_options.restart_home_assistant"
+ ),
+ });
+ }
+ const curEntry = this._params!.entry;
+ this._params!.entryUpdated({
+ ...curEntry,
+ system_options: {
+ ...curEntry.system_options,
+ ...data,
+ },
+ });
this._params = undefined;
} catch (err) {
this._error = err.message || "Unknown error";
@@ -150,20 +186,6 @@ class DialogConfigEntrySystemOptions extends LitElement {
return [
haStyleDialog,
css`
- .init-spinner {
- padding: 50px 100px;
- text-align: center;
- }
-
- .form {
- padding-top: 6px;
- padding-bottom: 24px;
- color: var(--primary-text-color);
- }
- .secondary {
- color: var(--secondary-text-color);
- }
-
.error {
color: var(--error-color);
}
diff --git a/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts b/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts
index 6b8a6c0329..77415e02cd 100644
--- a/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts
+++ b/src/dialogs/config-entry-system-options/show-dialog-config-entry-system-options.ts
@@ -1,12 +1,11 @@
import { fireEvent } from "../../common/dom/fire_event";
import { ConfigEntry } from "../../data/config_entries";
+import { IntegrationManifest } from "../../data/integration";
export interface ConfigEntrySystemOptionsDialogParams {
entry: ConfigEntry;
- // updateEntry: (
- // updates: Partial
- // ) => Promise;
- // removeEntry: () => Promise;
+ manifest?: IntegrationManifest;
+ entryUpdated(entry: ConfigEntry): void;
}
export const loadConfigEntrySystemOptionsDialog = () =>
diff --git a/src/dialogs/ha-store-auth-card.ts b/src/dialogs/ha-store-auth-card.ts
index b3229bfa73..6d7e5d3e8f 100644
--- a/src/dialogs/ha-store-auth-card.ts
+++ b/src/dialogs/ha-store-auth-card.ts
@@ -50,6 +50,9 @@ class HaStoreAuth extends LitElement {
bottom: 16px;
right: 16px;
transition: bottom 0.25s;
+ --ha-card-box-shadow: 0px 3px 5px -1px rgba(0, 0, 0, 0.2),
+ 0px 6px 10px 0px rgba(0, 0, 0, 0.14),
+ 0px 1px 18px 0px rgba(0, 0, 0, 0.12);
}
.card-actions {
diff --git a/src/panels/config/integrations/ha-integration-card.ts b/src/panels/config/integrations/ha-integration-card.ts
index cbd7de5aab..4e2a103c48 100644
--- a/src/panels/config/integrations/ha-integration-card.ts
+++ b/src/panels/config/integrations/ha-integration-card.ts
@@ -110,6 +110,7 @@ export class HaIntegrationCard extends LitElement {
: undefined}
.localizedDomainName=${item ? item.localized_domain_name : undefined}
.manifest=${this.manifest}
+ .configEntry=${item}
>
${this.items.length > 1
? html`
@@ -466,6 +467,11 @@ export class HaIntegrationCard extends LitElement {
private _showSystemOptions(configEntry: ConfigEntry) {
showConfigEntrySystemOptionsDialog(this, {
entry: configEntry,
+ manifest: this.manifest,
+ entryUpdated: (entry) =>
+ fireEvent(this, "entry-updated", {
+ entry,
+ }),
});
}
diff --git a/src/panels/config/integrations/ha-integration-header.ts b/src/panels/config/integrations/ha-integration-header.ts
index cd189da48b..d18ba01670 100644
--- a/src/panels/config/integrations/ha-integration-header.ts
+++ b/src/panels/config/integrations/ha-integration-header.ts
@@ -1,8 +1,9 @@
-import { mdiCloud, mdiPackageVariant } from "@mdi/js";
+import { mdiCloud, mdiPackageVariant, mdiSyncOff } from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-svg-icon";
+import { ConfigEntry } from "../../../data/config_entries";
import { domainToName, IntegrationManifest } from "../../../data/integration";
import { HomeAssistant } from "../../../types";
import { brandsUrl } from "../../../util/brands-url";
@@ -21,6 +22,8 @@ export class HaIntegrationHeader extends LitElement {
@property({ attribute: false }) public manifest?: IntegrationManifest;
+ @property({ attribute: false }) public configEntry?: ConfigEntry;
+
protected render(): TemplateResult {
let primary: string;
let secondary: string | undefined;
@@ -59,6 +62,15 @@ export class HaIntegrationHeader extends LitElement {
),
]);
}
+
+ if (this.configEntry?.system_options.disable_polling) {
+ icons.push([
+ mdiSyncOff,
+ this.hass.localize(
+ "ui.panel.config.integrations.config_entry.disabled_polling"
+ ),
+ ]);
+ }
}
return html`
diff --git a/src/state/auth-mixin.ts b/src/state/auth-mixin.ts
index 7800ce8433..21575adc33 100644
--- a/src/state/auth-mixin.ts
+++ b/src/state/auth-mixin.ts
@@ -33,7 +33,7 @@ export default >(superClass: T) =>
.then(() => {
const el = document.createElement("ha-store-auth-card");
this.provideHass(el);
- this.shadowRoot!.appendChild(el);
+ document.body.appendChild(el);
});
}
}
diff --git a/src/translations/en.json b/src/translations/en.json
index 584e25f33e..dae343b3c2 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -759,7 +759,10 @@
"config_entry_system_options": {
"title": "System Options for {integration}",
"enable_new_entities_label": "Enable newly added entities.",
- "enable_new_entities_description": "If disabled, newly discovered entities for {integration} will not be automatically added to Home Assistant.",
+ "enable_new_entities_description": "If newly discovered devices for {integration} should be automatically added.",
+ "enable_polling_label": "Enable polling for updates.",
+ "enable_polling_description": "If Home Assistant should automatically poll {integration} entities for updates.",
+ "restart_home_assistant": "You need to restart Home Assistant for your changes to take effect.",
"update": "Update"
},
"zha_reconfigure_device": {
@@ -2182,6 +2185,7 @@
},
"provided_by_custom_integration": "Provided by a custom integration",
"depends_on_cloud": "Depends on the cloud",
+ "disabled_polling": "Automatic polling for updated data disabled",
"state": {
"loaded": "Loaded",
"setup_error": "Failed to set up",
diff --git a/src/util/register-service-worker.ts b/src/util/register-service-worker.ts
index 709c8f2a6c..1a029f97d0 100644
--- a/src/util/register-service-worker.ts
+++ b/src/util/register-service-worker.ts
@@ -39,13 +39,12 @@ export const registerServiceWorker = async (
}
// Notify users a new frontend is available.
- // When
showToast(rootEl, {
message: "A new version of the frontend is available.",
action: {
// We tell the service worker to call skipWaiting, which activates
// the new service worker. Above we listen for `controllerchange`
- // so we reload the page once a new servic worker activates.
+ // so we reload the page once a new service worker activates.
action: () => installingWorker.postMessage({ type: "skipWaiting" }),
text: "reload",
},
diff --git a/translations/frontend/cs.json b/translations/frontend/cs.json
index f093bf9861..e65cdf03ff 100644
--- a/translations/frontend/cs.json
+++ b/translations/frontend/cs.json
@@ -385,8 +385,13 @@
"create_blocked_not_running": "Vytvoření zálohy není momentálně možné, protože systém je ve \"{state}\".",
"create_snapshot": "Vytvořit zálohu",
"created": "Vytvořeno",
+ "delete_selected": "Smazat vybrané zálohy",
+ "delete_snapshot_confirm": "smazat",
+ "delete_snapshot_text": "Chcete smazat {number} {number, plural,\n one {zálohu}\n few {zálohy}\n other {záloh}\n}?",
+ "delete_snapshot_title": "Smazat zálohu",
"description": "Zálohy umožňují snadno zálohovat a obnovovat všechna data vaší instance Home Assistant.",
"enter_password": "Prosím zadejte heslo.",
+ "failed_to_delete": "Smazání se nezdařilo",
"folder": {
"addons/local": "Místní doplňky",
"homeassistant": "Nastavení Home Asistent",
@@ -404,6 +409,7 @@
"password_protection": "Ochrana heslem",
"security": "Zabezpečení",
"select_type": "Vyberte, co chcete obnovit",
+ "selected": "{number} vybraných",
"type": "Typ zálohy",
"upload_snapshot": "Nahrát zálohu"
},
diff --git a/translations/frontend/da.json b/translations/frontend/da.json
index 2498e9f36e..ccd8b05d22 100644
--- a/translations/frontend/da.json
+++ b/translations/frontend/da.json
@@ -385,8 +385,13 @@
"create_blocked_not_running": "Det er ikke muligt at oprette et snapshot lige nu, fordi systemet er i tilstanden {state}.",
"create_snapshot": "Opret snapshot",
"created": "Oprettet",
+ "delete_selected": "Slet valgte snapshots",
+ "delete_snapshot_confirm": "Slet",
+ "delete_snapshot_text": "Vil du slette {number} \n{number, plural,\n one {snapshot}\n other {snapshots}\n}?",
+ "delete_snapshot_title": "Slet snapshot",
"description": "Snapshots giver dig mulighed for nemt at sikkerhedskopiere og gendanne alle data fra dit instans af Home Assistant.",
"enter_password": "Venligst indtast et kodeord.",
+ "failed_to_delete": "Kunne ikke slette",
"folder": {
"addons/local": "Lokale tilføjelsesprogrammer",
"homeassistant": "Home Assistant konfiguration",
@@ -403,6 +408,8 @@
"password_protected": "beskyttet med kodeord",
"password_protection": "Kodeordsbeskyttelse",
"security": "Sikkerhed",
+ "select_type": "Vælg, hvad der skal gendannes",
+ "selected": "{number} valgt",
"type": "Type",
"upload_snapshot": "Upload snapshot"
},
@@ -720,6 +727,9 @@
"no_match": "Ingen matchende områder fundet",
"show_areas": "Vis områder"
},
+ "attributes": {
+ "expansion_header": "Attributter"
+ },
"blueprint-picker": {
"add_user": "Tilføj bruger",
"remove_user": "Fjern bruger",
@@ -1719,6 +1729,7 @@
"title": "Alexa"
},
"connected": "Forbundet",
+ "connecting": "Forbinder...",
"connection_status": "Cloud-forbindelsesstatus",
"fetching_subscription": "Henter abonnement...",
"google": {
@@ -2588,6 +2599,8 @@
"add_scene": "Tilføj scene",
"delete_confirm": "Er du sikker på, at du vil slette denne scene?",
"delete_scene": "Slet scene",
+ "duplicate": "Kopier",
+ "duplicate_scene": "Kopier scene",
"edit_scene": "Rediger scene",
"header": "Sceneredigering",
"headers": {
@@ -2916,6 +2929,8 @@
"follow_device_instructions": "Følg instruktionerne, der fulgte med din enhed for at starte parring af enheden.",
"inclusion_failed": "Noden kunne ikke tilføjes. Se i logfilerne for at få flere oplysninger.",
"inclusion_finished": "Noden er blevet tilføjet. Det kan tage et par minutter før alle enheder dukker op, mens konfiguration af noden fuldføres.",
+ "interview_failed": "Forespørgsel af enheden er mislykkedes. Der kan være yderligere oplysninger i logfilerne.",
+ "interview_started": "Enheden forespørges. Dette kan tage noget tid.",
"introduction": "Denne guide hjælper dig med at føje en node til dit Z-Wave-netværk.",
"secure_inclusion_warning": "Sikre enheder kræver ekstra båndbredde. For mange sikre enheder kan gøre dit Z-Wave-netværk langsomt. Det anbefaler kun at bruge sikker inklusion til de enheder, hvor det er nødvendigt. For eksempel til låse eller garageportåbnere.",
"start_inclusion": "Start inklusionstilstand",
@@ -2955,6 +2970,7 @@
},
"logs": {
"log_level": "Log niveau",
+ "log_level_changed": "Logniveauet er ændret til: {level}",
"subscribed_to_logs": "Abboner på Z-Wave JS Log beskeder",
"title": "Z-Wave JS-logfiler"
},
@@ -4004,6 +4020,17 @@
"primary_color": "Primær farve",
"reset": "Nulstil"
},
+ "time_format": {
+ "description": "Vælg, hvordan klokkeslæt skal formateres.",
+ "dropdown_label": "Tidsformat",
+ "formats": {
+ "12": "12 timer (AM / PM)",
+ "24": "24 timer",
+ "language": "Automatisk (brug sprogindstilling)",
+ "system": "Brug systemets landestandard"
+ },
+ "header": "Tidsformat"
+ },
"vibrate": {
"description": "Aktivér eller deaktiver vibrationer på denne enhed, når du styrer enheder.",
"header": "Vibrer"
diff --git a/translations/frontend/en.json b/translations/frontend/en.json
index a2cade9a79..f076e43678 100644
--- a/translations/frontend/en.json
+++ b/translations/frontend/en.json
@@ -929,8 +929,11 @@
},
"dialogs": {
"config_entry_system_options": {
- "enable_new_entities_description": "If disabled, newly discovered entities for {integration} will not be automatically added to Home Assistant.",
+ "enable_new_entities_description": "If newly discovered devices for {integration} should be automatically added.",
"enable_new_entities_label": "Enable newly added entities.",
+ "enable_polling_description": "If Home Assistant should automatically poll {integration} entities for updates.",
+ "enable_polling_label": "Enable polling for updates.",
+ "restart_home_assistant": "You need to restart Home Assistant for your changes to take effect.",
"title": "System Options for {integration}",
"update": "Update"
},
@@ -2217,6 +2220,7 @@
},
"disabled_cause": "Disabled by {cause}"
},
+ "disabled_polling": "Automatic polling for updated data disabled",
"documentation": "Documentation",
"enable_restart_confirm": "Restart Home Assistant to finish enabling this integration",
"entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}",
diff --git a/translations/frontend/ko.json b/translations/frontend/ko.json
index 066fd0a1ea..16898e6ed1 100644
--- a/translations/frontend/ko.json
+++ b/translations/frontend/ko.json
@@ -385,8 +385,13 @@
"create_blocked_not_running": "시스템이 {state} 상태이기 때문에 지금은 스냅숏을 생성할 수 없습니다.",
"create_snapshot": "스냅숏 생성하기",
"created": "생성됨",
+ "delete_selected": "선택한 스냅샷 삭제",
+ "delete_snapshot_confirm": "삭제",
+ "delete_snapshot_text": "{number} {number, plural,\n one{개의 스냅샷}\n other{개의 스냅샷}\n}를 삭제하시겠습니까?",
+ "delete_snapshot_title": "스냅샷 삭제",
"description": "스냅숏을 사용하면 Home Assistant 인스턴스의 모든 데이터를 쉽게 백업하고 복원할 수 있습니다.",
"enter_password": "비밀번호를 입력해주세요.",
+ "failed_to_delete": "삭제하지 못했습니다.",
"folder": {
"addons/local": "로컬 애드온",
"homeassistant": "Home Assistant 구성 내용",
@@ -404,6 +409,7 @@
"password_protection": "비밀번호 보호",
"security": "보안",
"select_type": "복원 할 항목 선택",
+ "selected": "{number}개 선택됨",
"type": "유형",
"upload_snapshot": "스냅숏 올리기"
},
diff --git a/translations/frontend/nb.json b/translations/frontend/nb.json
index 375698e2b9..f5d487d89e 100644
--- a/translations/frontend/nb.json
+++ b/translations/frontend/nb.json
@@ -385,8 +385,13 @@
"create_blocked_not_running": "Å lage en sikkerhetskopi er ikke mulig akkurat nå fordi systemet er i {state} status",
"create_snapshot": "Opprett sikkerhetskopi",
"created": "Opprettet",
+ "delete_selected": "Slett valgte sikkerhetskopier",
+ "delete_snapshot_confirm": "slett",
+ "delete_snapshot_text": "Vl du slette {number} {number, plural,\n one {sikkerhetskopi}\n other {sikkerhetskopier}\n}?",
+ "delete_snapshot_title": "Slett sikkerhetskopi",
"description": "Sikkerhetskopier lar deg enkelt sikkerhetskopiere og gjenopprette alle dataene fra din Home Assistant forekomst",
"enter_password": "Vennligst skriv inn et passord",
+ "failed_to_delete": "Kunne ikke slette",
"folder": {
"addons/local": "Lokale tillegg",
"homeassistant": "Home Assistant-konfigurasjon",
@@ -404,6 +409,7 @@
"password_protection": "Passordbeskyttelse",
"security": "Sikkerhet",
"select_type": "Velg hva du vil gjenopprette",
+ "selected": "{number} valgt",
"type": "Type øyeblikksbilde",
"upload_snapshot": "Last opp sikkerhetskopi"
},
diff --git a/translations/frontend/pt-BR.json b/translations/frontend/pt-BR.json
index 90742292f6..67fa944000 100644
--- a/translations/frontend/pt-BR.json
+++ b/translations/frontend/pt-BR.json
@@ -713,9 +713,20 @@
},
"zha_reconfigure_device": {
"attribute": "Atributo",
+ "battery_device_warning": "Você precisará despertar os dispositivos alimentados por bateria antes de iniciar o processo de reconfiguração. Consulte o manual do seu dispositivo para obter instruções sobre como despertar o dispositivo.",
"bind_header": "Vinculação",
+ "button_hide": "Ocultar detalhes",
+ "button_show": "Mostrar detalhes",
+ "cluster_header": "Cluster",
+ "configuration_complete": "Reconfiguração do dispositivo concluída.",
+ "configuration_failed": "A reconfiguração do dispositivo falhou. Informações adicionais podem estar disponíveis nos logs.",
+ "configuring_alt": "Configurando",
+ "in_progress": "O dispositivo está sendo reconfigurado. Isto pode levar algum tempo.",
+ "introduction": "Reconfigure um dispositivo em sua rede Zigbee. Use este recurso se o seu dispositivo não estiver funcionando corretamente.",
"min_max_change": "min/máx/mudança",
- "reporting_header": "Relatório"
+ "reporting_header": "Relatório",
+ "run_in_background": "Você pode fechar esta caixa de diálogo e a reconfiguração continuará em segundo plano.",
+ "start_reconfiguration": "Iniciar reconfiguração"
}
},
"duration": {
@@ -770,6 +781,7 @@
"linked_entities_caption": "Entidades",
"name": "Nome",
"name_required": "Nome é obrigatório",
+ "no_linked_entities": "Não há entidades vinculadas a esta área.",
"unknown_error": "Erro desconhecido",
"update": "Atualizar"
},
@@ -2120,6 +2132,7 @@
"zwave_js": {
"logs": {
"log_level": "Nível de Log",
+ "log_level_changed": "Nível de Log mudou para: {level}",
"subscribed_to_logs": "Inscrito em mensagens de log JS do Z-Wave ...",
"title": "Logs Z-Wave JS"
},
diff --git a/translations/frontend/ru.json b/translations/frontend/ru.json
index fd7dcbf674..62a5597b76 100644
--- a/translations/frontend/ru.json
+++ b/translations/frontend/ru.json
@@ -219,7 +219,7 @@
},
"boot": {
"description": "Запускать дополнение во время загрузки системы",
- "title": "Запускать при загрузке"
+ "title": "Автозагрузка"
},
"ingress_panel": {
"description": "Добавить это дополнение на боковую панель",
diff --git a/translations/frontend/zh-Hans.json b/translations/frontend/zh-Hans.json
index eac6f6b64e..2e84844e56 100644
--- a/translations/frontend/zh-Hans.json
+++ b/translations/frontend/zh-Hans.json
@@ -387,7 +387,7 @@
"created": "创建于",
"delete_selected": "删除选定的快照",
"delete_snapshot_confirm": "删除",
- "delete_snapshot_text": "您是否要删除{number}个快照?",
+ "delete_snapshot_text": "是否要删除这 {number} 个快照?",
"delete_snapshot_title": "删除快照",
"description": "“快照”使您可以轻松地备份和还原 Home Assistant 实例的所有数据。",
"enter_password": "请输入密码。",
@@ -408,8 +408,8 @@
"password_protected": "密码保护",
"password_protection": "密码保护",
"security": "安全性",
- "select_type": "选择要还原的内容",
- "selected": "选择了 {number} 项",
+ "select_type": "请选择要还原的内容",
+ "selected": "已选择 {number} 项",
"type": "类型",
"upload_snapshot": "上传快照"
},
@@ -580,8 +580,8 @@
},
"lock": {
"code": "密码",
- "lock": "上锁",
- "unlock": "开锁"
+ "lock": "锁定",
+ "unlock": "解锁"
},
"media_player": {
"browse_media": "浏览媒体",
@@ -798,13 +798,13 @@
"was_closed": "已关闭",
"was_connected": "已连接",
"was_disconnected": "已断开",
- "was_locked": "已上锁",
+ "was_locked": "已锁定",
"was_low": "较低",
"was_normal": "正常",
"was_opened": "已打开",
"was_plugged_in": "已插入",
"was_safe": "[%key_id:6884522%]",
- "was_unlocked": "已打开",
+ "was_unlocked": "已解锁",
"was_unplugged": "已拔出",
"was_unsafe": "[%key_id:6884523%]"
},
@@ -1129,7 +1129,7 @@
"command_line": "命令行实体",
"core": "位置和自定义",
"filesize": "文件大小实体",
- "filter": "筛选实体",
+ "filter": "Filter 实体",
"generic": "通用 IP 摄像机实体",
"generic_thermostat": "通用恒温器实体",
"group": "分组、分组实体及其通知服务",
@@ -1803,7 +1803,7 @@
}
},
"alexa": {
- "banner": "您在configuration.yaml中配置了实体过滤器,因此无法用此UI修改被公开的实体名单。",
+ "banner": "由于您在 configuration.yaml 中配置了实体过滤器,无法通过此 UI 修改要开放的实体。",
"dont_expose_entity": "使实体不可发现",
"expose": "向Alexa发送你的位置",
"expose_entity": "使实体可发现",
@@ -2672,7 +2672,7 @@
"command_line": "命令行实体",
"core": "位置和自定义",
"filesize": "文件大小实体",
- "filter": "筛选实体",
+ "filter": "Filter 实体",
"generic": "通用 IP 摄像机实体",
"generic_thermostat": "通用恒温器实体",
"group": "分组、分组实体及其通知服务",
@@ -2970,7 +2970,7 @@
},
"logs": {
"log_level": "日志级别",
- "log_level_changed": "日志级别更改为: {level}",
+ "log_level_changed": "日志级别更改为: {level}",
"subscribed_to_logs": "已订阅 Z-Wave JS 日志消息...",
"title": "Z-Wave JS 日志"
},