From 2d056bad81127b74606a9875b0db87b008da3785 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 4 Jun 2019 08:47:02 -0700 Subject: [PATCH 1/4] Allow picking location on a map (#3244) * Allow picking location on a map * Add some better defaults * Close connection before navigation --- build-scripts/gulp/service-worker.js | 4 + src/common/dom/setup-leaflet-map.ts | 4 +- src/components/map/ha-location-editor.ts | 125 ++++++++++++++++++ src/onboarding/ha-onboarding.ts | 15 ++- src/onboarding/onboarding-core-config.ts | 87 +++++------- src/panels/config/core/ha-config-core-form.ts | 51 +++---- 6 files changed, 195 insertions(+), 91 deletions(-) create mode 100644 src/components/map/ha-location-editor.ts diff --git a/build-scripts/gulp/service-worker.js b/build-scripts/gulp/service-worker.js index 1303983790..d8cd421852 100644 --- a/build-scripts/gulp/service-worker.js +++ b/build-scripts/gulp/service-worker.js @@ -15,6 +15,10 @@ gulp.task("gen-service-worker-dev", (done) => { writeSW( ` console.debug('Service worker disabled in development'); + +self.addEventListener('install', (event) => { + self.skipWaiting(); +}); ` ); done(); diff --git a/src/common/dom/setup-leaflet-map.ts b/src/common/dom/setup-leaflet-map.ts index 1b3f300a8f..70d282d1b2 100644 --- a/src/common/dom/setup-leaflet-map.ts +++ b/src/common/dom/setup-leaflet-map.ts @@ -11,14 +11,14 @@ export const setupLeafletMap = async ( } // tslint:disable-next-line const Leaflet = (await import(/* webpackChunkName: "leaflet" */ "leaflet")) as LeafletModuleType; - Leaflet.Icon.Default.imagePath = "/static/images/leaflet"; + Leaflet.Icon.Default.imagePath = "/static/images/leaflet/images/"; const map = Leaflet.map(mapElement); const style = document.createElement("link"); style.setAttribute("href", "/static/images/leaflet/leaflet.css"); style.setAttribute("rel", "stylesheet"); mapElement.parentNode.appendChild(style); - map.setView([51.505, -0.09], 13); + map.setView([52.3731339, 4.8903147], 13); Leaflet.tileLayer( `https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}${ Leaflet.Browser.retina ? "@2x.png" : ".png" diff --git a/src/components/map/ha-location-editor.ts b/src/components/map/ha-location-editor.ts new file mode 100644 index 0000000000..9f3d45c01a --- /dev/null +++ b/src/components/map/ha-location-editor.ts @@ -0,0 +1,125 @@ +import { + LitElement, + property, + TemplateResult, + html, + CSSResult, + css, + customElement, + PropertyValues, +} from "lit-element"; +import { Marker, Map, LeafletMouseEvent, DragEndEvent, LatLng } from "leaflet"; +import { + setupLeafletMap, + LeafletModuleType, +} from "../../common/dom/setup-leaflet-map"; +import { fireEvent } from "../../common/dom/fire_event"; + +@customElement("ha-location-editor") +class LocationEditor extends LitElement { + @property() public location?: [number, number]; + public fitZoom = 16; + + private _ignoreFitToMap?: [number, number]; + + // tslint:disable-next-line + private Leaflet?: LeafletModuleType; + private _leafletMap?: Map; + private _locationMarker?: Marker; + + public fitMap(): void { + if (!this._leafletMap || !this.location) { + return; + } + this._leafletMap.setView(this.location, this.fitZoom); + } + + protected render(): TemplateResult | void { + return html` +
+ `; + } + + protected firstUpdated(changedProps: PropertyValues): void { + super.firstUpdated(changedProps); + this._initMap(); + } + + protected updated(changedProps: PropertyValues): void { + super.updated(changedProps); + + // Still loading. + if (!this.Leaflet) { + return; + } + + this._updateMarker(); + if (!this._ignoreFitToMap || this._ignoreFitToMap !== this.location) { + this.fitMap(); + } + this._ignoreFitToMap = undefined; + } + + private get _mapEl(): HTMLDivElement { + return this.shadowRoot!.querySelector("div")!; + } + + private async _initMap(): Promise { + [this._leafletMap, this.Leaflet] = await setupLeafletMap(this._mapEl); + this._leafletMap.addEventListener( + "click", + // @ts-ignore + (ev: LeafletMouseEvent) => this._updateLocation(ev.latlng) + ); + this._updateMarker(); + this.fitMap(); + this._leafletMap.invalidateSize(); + } + + private _updateLocation(latlng: LatLng) { + this.location = this._ignoreFitToMap = [latlng.lat, latlng.lng]; + fireEvent(this, "change", undefined, { bubbles: false }); + } + + private _updateMarker(): void { + if (!this.location) { + if (this._locationMarker) { + this._locationMarker.remove(); + this._locationMarker = undefined; + } + return; + } + + if (this._locationMarker) { + this._locationMarker.setLatLng(this.location); + return; + } + this._locationMarker = this.Leaflet!.marker(this.location, { + draggable: true, + }); + this._locationMarker.addEventListener( + "dragend", + // @ts-ignore + (ev: DragEndEvent) => this._updateLocation(ev.target.getLatLng()) + ); + this._leafletMap!.addLayer(this._locationMarker); + } + + static get styles(): CSSResult { + return css` + :host { + display: block; + height: 300px; + } + #map { + height: 100%; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-location-editor": LocationEditor; + } +} diff --git a/src/onboarding/ha-onboarding.ts b/src/onboarding/ha-onboarding.ts index 48f6d266ef..6c932a6326 100644 --- a/src/onboarding/ha-onboarding.ts +++ b/src/onboarding/ha-onboarding.ts @@ -84,8 +84,8 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); this._fetchOnboardingSteps(); - import("./onboarding-integrations"); - import("./onboarding-core-config"); + import(/* webpackChunkName: "onboarding-integrations" */ "./onboarding-integrations"); + import(/* webpackChunkName: "onboarding-core-config" */ "./onboarding-core-config"); registerServiceWorker(false); this.addEventListener("onboarding-step", (ev) => this._handleStepDone(ev)); } @@ -156,6 +156,15 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { const result = stepResult.result as OnboardingResponses["integration"]; this._loading = true; + // If we don't close the connection manually, the connection will be + // closed when we navigate away from the page. Firefox allows JS to + // continue to execute, and so HAWS will automatically reconnect once + // the connection is closed. However, since we revoke our token below, + // HAWS will reload the page, since that will trigger the auth flow. + // In Firefox, triggering a reload will overrule the navigation that + // was in progress. + this.hass!.connection.close(); + // Revoke current auth token. await this.hass!.auth.revoke(); @@ -184,6 +193,8 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) { this.initializeHass(auth, conn); // Load config strings for integrations (this as any)._loadFragmentTranslations(this.hass!.language, "config"); + // Make sure hass is initialized + the config/user callbacks have called. + await new Promise((resolve) => setTimeout(resolve, 0)); } } diff --git a/src/onboarding/onboarding-core-config.ts b/src/onboarding/onboarding-core-config.ts index 65c4841e59..2e163e01db 100644 --- a/src/onboarding/onboarding-core-config.ts +++ b/src/onboarding/onboarding-core-config.ts @@ -19,12 +19,14 @@ import { detectCoreConfig, saveCoreConfig, } from "../data/core"; -import { UNIT_C } from "../common/const"; import { PolymerChangedEvent } from "../polymer-types"; import { onboardCoreConfigStep } from "../data/onboarding"; import { fireEvent } from "../common/dom/fire_event"; import { LocalizeFunc } from "../common/translations/localize"; import { createTimezoneListEl } from "../components/timezone-datalist"; +import "../components/map/ha-location-editor"; + +const amsterdam = [52.3731339, 4.8903147]; @customElement("onboarding-core-config") class OnboardingCoreConfig extends LitElement { @@ -34,8 +36,7 @@ class OnboardingCoreConfig extends LitElement { @property() private _working = false; @property() private _name!: ConfigUpdateValues["location_name"]; - @property() private _latitude!: string; - @property() private _longitude!: string; + @property() private _location!: [number, number]; @property() private _elevation!: string; @property() private _unitSystem!: ConfigUpdateValues["unit_system"]; @property() private _timeZone!: string; @@ -82,26 +83,12 @@ class OnboardingCoreConfig extends LitElement {
- - + .location=${this._locationValue} + .fitZoom=${14} + @change=${this._locationChanged} + >
@@ -205,36 +192,20 @@ class OnboardingCoreConfig extends LitElement { ); } - private get _latitudeValue() { - return this._latitude !== undefined - ? this._latitude - : this.hass.config.latitude; - } - - private get _longitudeValue() { - return this._longitude !== undefined - ? this._longitude - : this.hass.config.longitude; + private get _locationValue() { + return this._location || amsterdam; } private get _elevationValue() { - return this._elevation !== undefined - ? this._elevation - : this.hass.config.elevation; + return this._elevation !== undefined ? this._elevation : 0; } private get _timeZoneValue() { - return this._timeZone !== undefined - ? this._timeZone - : this.hass.config.time_zone; + return this._timeZone; } private get _unitSystemValue() { - return this._unitSystem !== undefined - ? this._unitSystem - : this.hass.config.unit_system.temperature === UNIT_C - ? "metric" - : "imperial"; + return this._unitSystem !== undefined ? this._unitSystem : "metric"; } private _handleChange(ev: PolymerChangedEvent) { @@ -242,6 +213,10 @@ class OnboardingCoreConfig extends LitElement { this[`_${target.name}`] = target.value; } + private _locationChanged(ev) { + this._location = ev.currentTarget.location; + } + private _unitSystemChanged( ev: PolymerChangedEvent ) { @@ -252,14 +227,17 @@ class OnboardingCoreConfig extends LitElement { this._working = true; try { const values = await detectCoreConfig(this.hass); - for (const key in values) { - if (key === "unit_system") { - this._unitSystem = values[key]!; - } else if (key === "time_zone") { - this._timeZone = values[key]!; - } else { - this[`_${key}`] = values[key]; - } + if (values.latitude && values.longitude) { + this._location = [Number(values.latitude), Number(values.longitude)]; + } + if (values.elevation) { + this._elevation = String(values.elevation); + } + if (values.unit_system) { + this._unitSystem = values.unit_system; + } + if (values.time_zone) { + this._timeZone = values.time_zone; } } catch (err) { alert(`Failed to detect location information: ${err.message}`); @@ -272,13 +250,14 @@ class OnboardingCoreConfig extends LitElement { ev.preventDefault(); this._working = true; try { + const location = this._locationValue; await saveCoreConfig(this.hass, { location_name: this._nameValue, - latitude: Number(this._latitudeValue), - longitude: Number(this._longitudeValue), + latitude: location[0], + longitude: location[1], elevation: Number(this._elevationValue), unit_system: this._unitSystemValue, - time_zone: this._timeZoneValue, + time_zone: this._timeZoneValue || "UTC", }); const result = await onboardCoreConfigStep(this.hass); fireEvent(this, "onboarding-step", { diff --git a/src/panels/config/core/ha-config-core-form.ts b/src/panels/config/core/ha-config-core-form.ts index 94d25fed73..9f10446924 100644 --- a/src/panels/config/core/ha-config-core-form.ts +++ b/src/panels/config/core/ha-config-core-form.ts @@ -19,6 +19,7 @@ import { PaperInputElement } from "@polymer/paper-input/paper-input"; import { UNIT_C } from "../../../common/const"; import { ConfigUpdateValues, saveCoreConfig } from "../../../data/core"; import { createTimezoneListEl } from "../../../components/timezone-datalist"; +import "../../../components/map/ha-location-editor"; @customElement("ha-config-core-form") class ConfigCoreForm extends LitElement { @@ -26,8 +27,8 @@ class ConfigCoreForm extends LitElement { @property() private _working = false; - @property() private _latitude!: string; - @property() private _longitude!: string; + @property() private _location!: [number, number]; + @property() private _elevation!: string; @property() private _unitSystem!: ConfigUpdateValues["unit_system"]; @property() private _timeZone!: string; @@ -56,26 +57,11 @@ class ConfigCoreForm extends LitElement { : ""}
- - + .location=${this._locationValue} + @change=${this._locationChanged} + >
@@ -176,16 +162,10 @@ class ConfigCoreForm extends LitElement { input.inputElement.appendChild(createTimezoneListEl()); } - private get _latitudeValue() { - return this._latitude !== undefined - ? this._latitude - : this.hass.config.latitude; - } - - private get _longitudeValue() { - return this._longitude !== undefined - ? this._longitude - : this.hass.config.longitude; + private get _locationValue() { + return this._location !== undefined + ? this._location + : [Number(this.hass.config.latitude), Number(this.hass.config.longitude)]; } private get _elevationValue() { @@ -213,6 +193,10 @@ class ConfigCoreForm extends LitElement { this[`_${target.name}`] = target.value; } + private _locationChanged(ev) { + this._location = ev.currentTarget.location; + } + private _unitSystemChanged( ev: PolymerChangedEvent ) { @@ -222,9 +206,10 @@ class ConfigCoreForm extends LitElement { private async _save() { this._working = true; try { + const location = this._locationValue; await saveCoreConfig(this.hass, { - latitude: Number(this._latitudeValue), - longitude: Number(this._longitudeValue), + latitude: location[0], + longitude: location[1], elevation: Number(this._elevationValue), unit_system: this._unitSystemValue, time_zone: this._timeZoneValue, From 21ed717287d543e8bc8b6a092d7c2bfd5f4d0a0d Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 4 Jun 2019 08:47:40 -0700 Subject: [PATCH 2/4] Link to beta release notes for beta release in hassio (#3243) --- hassio/src/dashboard/hassio-hass-update.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hassio/src/dashboard/hassio-hass-update.js b/hassio/src/dashboard/hassio-hass-update.js index d401ec5840..8945dfab54 100644 --- a/hassio/src/dashboard/hassio-hass-update.js +++ b/hassio/src/dashboard/hassio-hass-update.js @@ -41,10 +41,11 @@ class HassioHassUpdate extends PolymerElement { >Update Release notes + Release notes +
@@ -84,6 +85,12 @@ class HassioHassUpdate extends PolymerElement { computeUpdateAvailable(hassInfo) { return hassInfo.version !== hassInfo.last_version; } + + computeReleaseNotesUrl(version) { + return `https://${ + version.includes("b") ? "rc" : "www" + }.home-assistant.io/latest-release-notes/`; + } } customElements.define("hassio-hass-update", HassioHassUpdate); From bb60b42f9854f25cde0bccb2362c226dbe980130 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 4 Jun 2019 08:48:37 -0700 Subject: [PATCH 3/4] Update translations --- translations/fa.json | 413 ++++++++++++++++++++++++++++++++++++++-- translations/pl.json | 4 +- translations/pt-BR.json | 194 ++++++++++++++++--- translations/sv.json | 7 +- 4 files changed, 577 insertions(+), 41 deletions(-) diff --git a/translations/fa.json b/translations/fa.json index e0ee8b37b0..47e6a4af72 100644 --- a/translations/fa.json +++ b/translations/fa.json @@ -61,7 +61,7 @@ "on": "شناسایی شد" }, "vibration": { - "off": "عادی", + "off": "پاک کردن", "on": "شناسایی شد" }, "opening": { @@ -75,6 +75,28 @@ "presence": { "off": "بیرون", "on": "خانه" + }, + "cold": { + "off": "عادی" + }, + "door": { + "off": "بسته", + "on": "باز" + }, + "garage_door": { + "off": "بسته", + "on": "باز" + }, + "heat": { + "off": "عادی" + }, + "window": { + "off": "بسته", + "on": "باز" + }, + "lock": { + "off": "قفل", + "on": "باز" } }, "calendar": { @@ -129,7 +151,7 @@ "not_home": "بیرون", "open": "باز", "opening": "در حال باز شدن", - "closed": "بسته شده", + "closed": "بسته", "closing": "در حال بسته شدن", "stopped": "متوقف", "locked": "قفل شده", @@ -166,7 +188,7 @@ "on": "روشن" }, "scene": { - "scening": "فعال" + "scening": "صحنه" }, "script": { "off": "غیرفعال", @@ -193,7 +215,7 @@ }, "query_stage": { "initializing": "در حال آماده شدن ({query_stage})", - "dead": "مرده ({query_stage})" + "dead": "قطع ({query_stage})" } }, "weather": { @@ -204,38 +226,364 @@ "rainy": "بارانی", "snowy": "برفی", "sunny": "آفتابی" + }, + "person": { + "home": "خانه", + "not_home": "بیرون" } }, "state_badge": { "default": { "unknown": "نامشخص", - "unavailable": "غیر قابل دسترس" + "unavailable": "غیر قابل دسترس", + "error": "خطا", + "entity_not_found": "نهاد یافت نشد" }, "alarm_control_panel": { "armed": "مصلح شده", "disarmed": "غیر مسلح", - "armed_home": "مسلح شده خانه", - "armed_away": "مسلح شده بیرون", - "armed_night": "مسلح شده شب", + "armed_home": "تجهیزات خانه", + "armed_away": "تجهیزات بیرون", + "armed_night": "تجهیزات شب", "pending": "در انتظار", "arming": "در حال مسلح کردن", "disarming": "در حال غیر مسلح کردن", "triggered": "راه انداخته شده", - "armed_custom_bypass": "مسلح شده" + "armed_custom_bypass": "مجهز" }, "device_tracker": { "home": "خانه", "not_home": "بیرون" + }, + "person": { + "home": "خانه", + "not_home": "بیرون" } }, "ui": { "sidebar": { - "log_out": "خروج" + "log_out": "خروج", + "external_app_configuration": "پیکربندی برنامه" + }, + "duration": { + "day": "\n{count} {count, plural,\n one {روز}\n other {روز ها}\n}\n", + "week": "\n{count} {count, plural,\n one {هفته}\n other {هفته ها}\n}\n", + "second": "ویرایشگر اتوماسیون اجازه می دهد تا شما را به ایجاد و ویرایش اتوماسیون بپردازید. لطفا پیوند زیر را بخوانید تا دستورالعمل ها را متوجه بشید تا مطمئن شوید که صفحه اصلی دستیار را به درستی پیکربندی کرده اید." }, "panel": { "config": { + "core": { + "section": { + "core": { + "header": "پیکربندی و کنترل سرور", + "reloading": { + "core": "بارگذاری مجدد ", + "automation": "بازنگری automations", + "script": "بازنگری اسکریپت" + }, + "core_config": { + "edit_requires_storage": "ویرایشگر غیرفعال شده است چون پیکربندی ذخیره شده در configuration.yaml.", + "location_name": "نام برای نصب صفحه اصلی دستیار شما", + "latitude": "طول و عرض جغرافیایی", + "longitude": "جغرافیایی", + "elevation": "ارتفاع", + "elevation_meters": "متر", + "time_zone": "منطقه زمانی", + "unit_system": "واحد سیستم", + "unit_system_imperial": "امپریال", + "unit_system_metric": "متر", + "imperial_example": "فارنهایت، پوند", + "metric_example": "سانتیگراد، کیلوگرم", + "save_button": "ذخیره" + } + } + } + }, + "automation": { + "caption": "اتوماسیون", + "description": "ایجاد و ویرایش اتوماسیون", + "picker": { + "header": "ویرایشگر اتوماسیون", + "introduction": "ویرایشگر اتوماسیون اجازه می دهد تا شما را به ایجاد و ویرایش اتوماسیون بپردازید . لطفا پیوند زیر را بخوانید تا دستورالعمل ها را بخواند تا مطمئن شوید که صفحه اصلی دستیار را به درستی پیکربندی کرده اید.", + "pick_automation": "انتخاب اتوماسیون برای ویرایش" + }, + "editor": { + "save": "ذخیره", + "triggers": { + "introduction": "راه حلی است که پردازش یک قانون اتوماسیون را آغاز می کند. ممکن است چند عامل برای یک قاعده مشخص شود. هنگامی که یک ماشه شروع می شود، Home Assistant شرایط را تایید می کند، اگر وجود داشته باشد، و اقدام را فراخوانی می کند.", + "delete": "حذف", + "type": { + "sun": { + "event": "اتفاق" + }, + "zone": { + "zone": "منطقه", + "event": "اتفاق" + }, + "webhook": { + "label": "Webhook", + "webhook_id": "شناسه Webhook" + }, + "geo_location": { + "label": "موقعیت جغرافیایی", + "source": "منبع", + "zone": "منطقه", + "event": "رویداد:", + "enter": "ورود", + "leave": "ترک کردن" + } + } + }, + "conditions": { + "introduction": "شرایط یک بخش اختیاری از یک قانون اتوماسیون است و می تواند مورد استفاده قرار گیرد تا از وقوع رویداد زمانی که باعث ایجاد فعالیت می شود جلوگیری شود. شرایط بسیار شبیه به ماژورها هستند اما خیلی متفاوت هستند. یک ماشه به حوادث اتفاق می افتد در سیستم نگاه کنید، در حالی که یک وضعیت فقط به نظر می رسد که سیستم به نظر می رسد در حال حاضر. یک ماشه می تواند مشاهده کند که سوئیچ روشن است. یک وضعیت فقط می تواند ببینید که آیا یک سوئیچ در حال حاضر روشن یا خاموش است.", + "duplicate": "نمایش مطالب برای", + "delete": "حذف", + "delete_confirm": "مطمئنا میخواهید حذف کنید؟", + "unsupported_condition": "شرایط غیرقابل پشتیبانی: {condition}", + "type": { + "state": { + "label": "حالت", + "state": "حالت" + }, + "numeric_state": { + "label": "Numeric state", + "above": "بالاتر", + "below": "پایین تر", + "value_template": "قالب مقدار (اختیاری)" + }, + "sun": { + "label": "آفتاب" + }, + "template": { + "label": "قالب", + "value_template": "مقدار قالب" + }, + "time": { + "label": "زمان" + }, + "zone": { + "label": "منطقه", + "entity": "وجود با محل", + "zone": "منطقه" + } + } + }, + "actions": { + "introduction": "این اقدامات همان چیزی است که دستیار خانه انجام می دهد وقتی که اتوماسیون راه اندازی می شود.", + "duplicate": "دوبل کردن", + "delete": "حذف", + "delete_confirm": "مطمئنا میخواهید حذف کنید؟", + "unsupported_action": "عمل پشتیبانی نشده: {action}", + "type": { + "delay": { + "delay": "تاخیر" + }, + "event": { + "event": "اتفاق", + "service_data": "اطلاعات خدمات" + } + } + }, + "load_error_not_editable": "فقط اتوماسیون در automations.yaml قابل ویرایش هستند.", + "load_error_unknown": "خطا در بارگذاری اتوماسیون ({err_no})." + } + }, "zwave": { "caption": "Z-Wave" + }, + "integrations": { + "config_entry": { + "no_device": " بدون دستگاه", + "no_area": "بدون منطقه" + }, + "config_flow": { + "external_step": { + "description": "این مرحله نیاز به بازدید از وب سایت خارجی دارد که باید تکمیل شود.", + "open_site": "باز کردن سایت" + } + } + }, + "zha": { + "caption": "ZHA", + "description": " صفحه اصلی اتوماسیون مدیریت شبکه Zigbee", + "services": { + "reconfigure": "دستگاه ZHA پیکربندی مجدد (تعمیر دستگاه). از این استفاده کنید اگر با دستگاه مشکل دارید. اگر دستگاه مورد نظر یک دستگاه باتری است ، لطفا اطمینان حاصل شود که هنگام استفاده از این سرویس ، دستورات بیدار و پذیرش است.", + "updateDeviceName": "یک نام سفارشی برای این دستگاه در رجیستری دستگاه تنظیم کنید.", + "remove": "یک دستگاه را از شبکه ZigBee حذف کنید." + }, + "device_card": { + "device_name_placeholder": "نام کاربر داده شده", + "area_picker_label": "منطقه", + "update_name_button": "به روز رسانی نام" + }, + "add_device_page": { + "header": " صفحه اصلی اتوماسیون مدیریت شبکه Zigbee", + "spinner": "جستجو برای دستگاه های ZHY Zigbee ...", + "discovery_text": "دستگاه های کشف شده در اینجا نشان داده می شوند. دستورالعمل های دستگاه (های) خود را دنبال کنید و دستگاه (های) را در حالت جفت قرار دهید." + } + }, + "area_registry": { + "caption": "ثبت نام منطقه", + "description": "بررسی کلیه مناطق خانه شما", + "picker": { + "header": "ثبت منطقه", + "introduction": "مناطق برای سازمان دهی دستگاه های جاسازی شده استفاده می شوند. این اطلاعات در سراسر دستیار خانگی برای کمک به شما در سازماندهی رابط کاربری، مجوزها و ادغام با دیگر سیستم ها مورد استفاده قرار می گیرد.", + "introduction2": "برای قرار دادن دستگاه در یک منطقه، از پیوند زیر برای حرکت به صفحه ی ادغام استفاده کنید و سپس روی ادغام پیکربندی شوید تا به کارت دستگاه دسترسی پیدا کنید.", + "no_areas": "به نظر می رسد هنوز هیچ زمینه ای ندارید", + "create_area": "ایجاد منطقه" + }, + "create_area": "ایجاد منطقه", + "editor": { + "delete": "حذف", + "update": "به روز رسانی", + "create": "ايجاد كردن" + } + }, + "entity_registry": { + "caption": "ثبت منطقه", + "description": "مرور کلیه اشخاص شناخته شده.", + "picker": { + "header": "ثبت منطقه", + "unavailable": "(در دسترس نیست)", + "introduction": "دستیار خانه نگهداری رجیستری از هر نهاد که تا به حال دیده است که می تواند منحصر به فرد شناسایی شده است. هر یک از این نهاد ها یک شناسه نهادی اختصاص داده است که فقط برای این نهاد محفوظ خواهد ماند.", + "introduction2": "از رجیستر entity استفاده کنید تا نام را عوض کند، شناسه موجودیت را تغییر دهید یا ورودی را از صفحه اصلی دستیار حذف کنید. توجه داشته باشید، از بین بردن ورودی رجیستر entity entity entity را حذف نخواهد کرد. برای انجام این کار، پیوند زیر را دنبال کنید و آن را از صفحه ی ادغام حذف کنید.", + "integrations_page": "صفحه ادغام" + }, + "editor": { + "unavailable": "این نهاد در حال حاضر در دسترس نیست", + "delete": "حذف", + "update": "به روز رسانی" + } + }, + "customize": { + "picker": { + "introduction": "نویسه ویژگی های هر سازمانی. سفارشی سازی اضافه شده \/ ویرایش شده فورا اثر می کند. سفارشی های حذف شده هنگامی که موجودیت به روز می شود اثر می کند." + } + }, + "person": { + "description": "مدیریت افراد خانه هوشمند", + "detail": { + "device_tracker_intro": "دستگاه هایی که متعلق به این شخص هستند را انتخاب کنید.", + "device_tracker_picked": "پیگیری دستگاه", + "device_tracker_pick": "دستگاه را برای پیگیری انتخاب کنید" + } + }, + "cloud": { + "description_features": "کنترل کردن از خانه، ادغام با Alexa و Google Assistant." + } + }, + "profile": { + "push_notifications": { + "description": "ارسال اعلان ها به این دستگاه" + }, + "refresh_tokens": { + "description": "هر نشانه بازخوانی نشان دهنده یک جلسه ورود به سیستم است. هنگام خروج از سیستم ، نشانه های تازه سازی به صورت خودکار حذف می شوند. نشانه های تازه سازی زیر در حال حاضر برای حساب شما فعال هستند.", + "token_title": "تازه token برای {clientId}", + "delete_failed": "token حذف نشد.", + "current_token_tooltip": "عدم امکان حذف تازه کردن​ token" + }, + "long_lived_access_tokens": { + "confirm_delete": "آیا مطمئن هستید که میخواهید token زیر را برای {name} حذف کنید؟" + } + }, + "page-authorize": { + "authorizing_client": "شما در مورد ارائه {clientId} به عنوان مثال دستیار Home Assistant هستید.", + "form": { + "providers": { + "legacy_api_password": { + "abort": { + "login_expired": "لطفا دوباره وارد شوید." + } + }, + "command_line": { + "step": { + "init": { + "data": { + "username": "نام کاربری", + "password": "پسورد" + } + }, + "mfa": { + "data": { + "code": "تایید دو مرحله ای" + }, + "description": "** {mfa_module_name} ** را بر روی دستگاه خود باز کنید تا کد تأیید اعتبار دو نفره خود را ببینید و هویت خود را تأیید کنید:" + } + }, + "error": { + "invalid_auth": "کد احراز هویت نامعتبر" + } + } + } + } + }, + "lovelace": { + "editor": { + "edit_card": { + "save": "ذخیره", + "pick_card": "کارتی را که می خواهید اضافه کنید انتخاب کنید ؛", + "edit": "ویرایش", + "delete": "حذف" + }, + "save_config": { + "header": "کنترل UI Lovelace خود را بگیرید", + "para_sure": "آیا مطمئن هستید که میخواهید کنترل رابط کاربری خود را کنترل کنید؟" + }, + "menu": { + "raw_editor": "ویرایشگر اتوماسیون" + }, + "raw_editor": { + "header": "ویرایش پیکربندی", + "save": "ذخیره", + "unsaved_changes": "تغییرات ذخیره نشده", + "saved": "ذخیره" + } + }, + "cards": { + "empty_state": { + "title": "به خانه خوش آمدی", + "no_devices": "این صفحه به شما اجازه می دهد تا دستگاه های خود را کنترل کنید، با این حال به نظر می رسد که هیچ دستگاهی تنظیم نشده است. برای شروع به صفحه ادغام بروید.", + "go_to_integrations_page": "به صفحه ادغام بروید." + }, + "picture-elements": { + "hold": "نگه دارید:", + "tap": "ضربه زدن:", + "navigate_to": "رفتن به {location}", + "toggle": "تغییر {name}", + "call_service": "سرویس تماس {name}", + "more_info": "نمایش اطلاعات بیشتر: {name}" + } + }, + "warning": { + "entity_non_numeric": "نهاد غیر عددی است: {entity}" + }, + "changed_toast": { + "message": "پیکربندی Lovelace به روز شد، آیا مایل به بروزرسانی هستید؟", + "refresh": "تازه کردن" + }, + "reload_lovelace": "بازنگری Lovelace" + }, + "page-onboarding": { + "user": { + "data": { + "password_confirm": "تایید رمز عبور" + }, + "error": { + "password_not_match": "رمزهای عبور مطابقت ندارند" + } + }, + "integration": { + "intro": "دستگاه ها و خدمات در دستیار خانگی به صورت یکپارچه ارائه می شوند. اکنون می توانید آنها را تنظیم کنید یا بعدا از صفحه تنظیمات استفاده کنید.", + "more_integrations": "بیشتر", + "finish": "پایان" + }, + "core-config": { + "intro": "سلام {name} ، به دستیار خانگی خوش آمدید چگونه می خواهید خانه خود را نام ببرید؟", + "intro_location": "ما می خواهیم بدانیم کجا زندگی می کنیم این اطلاعات برای نمایش اطلاعات و تنظیم خودکار اتوماسیون مبتنی بر آفتاب کمک خواهد کرد. این اطلاعات در خارج از شبکه شما به اشتراک گذاشته نمیشود .", + "intro_location_detect": "ما می تواند کمک به شما در پر کردن این اطلاعات با ساخت یک درخواست به یک سرویس خارجی.", + "location_name_default": "خانه", + "button_detect": "تشخیص", + "finish": "بعدی" } } }, @@ -254,15 +602,58 @@ "se": "جنوب شرقی" }, "forecast": "پیش بینی" + }, + "alarm_control_panel": { + "arm_night": "نوبت شب", + "arm_custom_bypass": "بایگانی سفارشی" } + }, + "notification_toast": { + "entity_turned_off": "خاموش {نهاد}." + }, + "dialogs": { + "more_info_settings": { + "save": "ذخیره", + "name": "باطل کردن" + }, + "more_info_control": { + "sun": { + "elevation": "ارتفاع", + "rising": "افزایش", + "setting": "تنظیمات" + } + } + }, + "auth_store": { + "confirm": "ذخیره ورود به سیستم" + }, + "common": { + "save": "ذخیره" } }, "domain": { - "zwave": "Z-Wave" + "zwave": "Z-Wave", + "zha": "ZHA", + "lovelace": "Lovelace", + "person": "فرد" }, "attribute": { "weather": { "humidity": "رطوبت" } + }, + "state_attributes": { + "climate": { + "fan_mode": { + "off": "خاموش", + "on": "روشن", + "auto": "خودکار" + } + } + }, + "groups": { + "system-admin": "مدیران", + "system-users": "کاربران", + "system-read-only": "کاربران فقط خواندنی" } } \ No newline at end of file diff --git a/translations/pl.json b/translations/pl.json index 0bfcf3cba6..6d6b098af8 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -77,8 +77,8 @@ "on": "otwarte" }, "safety": { - "off": "zabezpieczony", - "on": "niezabezpieczony" + "off": "brak zagrożenia", + "on": "zagrożenie" }, "presence": { "off": "poza domem", diff --git a/translations/pt-BR.json b/translations/pt-BR.json index 14c4a14177..184135e376 100644 --- a/translations/pt-BR.json +++ b/translations/pt-BR.json @@ -237,7 +237,7 @@ }, "query_stage": { "initializing": "", - "dead": "" + "dead": "Dead ({query_stage})" } }, "weather": { @@ -279,7 +279,9 @@ "state_badge": { "default": { "unknown": "Desconhecido", - "unavailable": "Indisponível" + "unavailable": "Indisponível", + "error": "Erro", + "entity_not_found": "Entidade não encontrada" }, "alarm_control_panel": { "armed": "Armado", @@ -296,6 +298,10 @@ "device_tracker": { "home": "Em casa", "not_home": "Ausente" + }, + "person": { + "home": "Home", + "not_home": "Longe" } }, "ui": { @@ -327,7 +333,7 @@ "description": "Valide seu arquivo de configuração e controle o servidor", "section": { "core": { - "header": "Configuração e controle do servidor", + "header": "Configuração e Controle do Servidor", "introduction": "Alterar sua configuração pode ser um processo cansativo. Nós sabemos. Esta seção tentará tornar sua vida um pouco mais fácil.", "validation": { "heading": "Validação de configuração", @@ -349,6 +355,21 @@ "introduction": "Controle seu servidor do Home Assistant... A partir do Home Assistant.", "restart": "Reiniciar", "stop": "Parar" + }, + "core_config": { + "edit_requires_storage": "Editor desativado porque config armazenado em configuration.yaml.", + "location_name": "Nome da sua instalação do Home Assistant", + "latitude": "Latitude", + "longitude": "Longitude", + "elevation": "Elevação", + "elevation_meters": "metros", + "time_zone": "Fuso horário", + "unit_system": "Sistema de unidade", + "unit_system_imperial": "Imperial", + "unit_system_metric": "Métrico", + "imperial_example": "Fahrenheit, libras", + "metric_example": "Celsius, quilogramas", + "save_button": "Salvar" } } } @@ -357,7 +378,8 @@ "caption": "Customização", "description": "Personalizar suas entidades", "picker": { - "header": "Personalização" + "header": "Personalização", + "introduction": "Ajustar atributos por entidade. As personalizações adicionadas \/ editadas entrarão em vigor imediatamente. As personalizações removidas entrarão em vigor quando a entidade for atualizada." } }, "automation": { @@ -365,7 +387,7 @@ "description": "Criar e editar automações", "picker": { "header": "Editor de automação", - "introduction": "O editor de automação permite que você crie e edite automações. Por favor leia [as instruções](https:\/\/home-assistant.io\/docs\/automation\/editor\/) para certificar-se que configurou o Home Assistant corretamente.", + "introduction": "O editor de automação permite criar e editar automações. Por favor, siga o link abaixo para ler as instruções para se certificar de que você configurou o Home Assistant corretamente.", "pick_automation": "Escolha uma automação para editar", "no_automations": "Não encontramos nenhuma automação editável", "add_automation": "Adicionar automação", @@ -379,7 +401,7 @@ "alias": "Nome", "triggers": { "header": "Gatilhos", - "introduction": "Os gatilhos são o que iniciam o processamento das regras de automações. É possível especificar múltiplos gatilhos para a mesma regra. Quando o gatilho inicia, o Home Assistant vai validar as condições, se existirem, e iniciar as ações.\n\n[Veja mais sobre gatilhos.](https:\/\/home-assistant.io\/docs\/automation\/trigger\/)", + "introduction": "Triggers são o que inicia o processamento de uma regra de automação. É possível especificar vários gatilhos para a mesma regra. Quando o gatilho é iniciado, o Assistente Inicial validará as condições, se houver, e chamará a ação.", "add": "Adicionar gatilho", "duplicate": "Duplicar", "delete": "Apagar", @@ -452,14 +474,16 @@ "label": "Geolocalização", "source": "Origem", "zone": "Zona", - "event": "Evento:" + "event": "Evento:", + "enter": "Entrar", + "leave": "Sair" } }, "learn_more": "Saiba mais sobre gatilhos" }, "conditions": { "header": "Condições", - "introduction": "As condições são uma parte opcional de uma regra de automação e podem ser usadas para impedir que uma ação aconteça quando acionada. As condições são muito semelhantes aos gatilhos, mas são muito diferentes. Um gatilho examinará os eventos que estão ocorrendo no sistema, enquanto uma condição examina apenas a aparência do sistema no momento. Um disparador pode observar que um interruptor está sendo ligado. Uma condição só pode ver se um switch está atualmente ativado ou desativado.\n\n [Saiba mais sobre as condições.](https:\/\/home-assistant.io\/docs\/scripts\/conditions\/)", + "introduction": "As condições são uma parte opcional de uma regra de automação e podem ser usadas para impedir que uma ação aconteça quando acionada. As condições parecem muito semelhantes aos gatilhos, mas são muito diferentes. Um gatilho analisará os eventos que estão ocorrendo no sistema, enquanto uma condição apenas analisa a aparência do sistema no momento. Um disparador pode observar que um comutador está sendo ligado. Uma condição só pode ver se um interruptor está atualmente ativado ou desativado.", "add": "Adicionar condição", "duplicate": "Duplicar", "delete": "Apagar", @@ -505,7 +529,7 @@ }, "actions": { "header": "Ações", - "introduction": "As ações são as que o Home Assistant irá executar quando a automação for iniciada.", + "introduction": "As ações são o que o Home Assistant fará quando a automação for acionada.", "add": "Adicionar ação", "duplicate": "Duplicar", "delete": "Apagar", @@ -536,7 +560,9 @@ } }, "learn_more": "Saiba mais sobre ações" - } + }, + "load_error_not_editable": "Somente automações em automations.yaml são editáveis.", + "load_error_unknown": "Erro ao carregar a automação ({err_no})." } }, "script": { @@ -572,7 +598,8 @@ "cloud": { "caption": "Home Assistant Cloud", "description_login": "Conectado como {email}", - "description_not_login": "Não logado" + "description_not_login": "Não logado", + "description_features": "Controle fora de casa, integrar com Alexa e Google Assistant." }, "integrations": { "caption": "Integrações", @@ -591,11 +618,46 @@ "hub": "Conectado via", "firmware": "Firmware: {version}", "device_unavailable": "dispositivo indisponível", - "entity_unavailable": "entidade indisponível" + "entity_unavailable": "entidade indisponível", + "no_area": "Sem área" + }, + "config_flow": { + "external_step": { + "description": "Esta etapa exige que você visite um site externo para ser concluído.", + "open_site": "Abrir site" + } + } + }, + "zha": { + "caption": "ZHA", + "description": "Gerenciamento de rede Zigbee Home Automation", + "services": { + "reconfigure": "Reconfigure o dispositivo ZHA (curar dispositivo). Use isto se você estiver tendo problemas com o dispositivo. Se o dispositivo em questão for um dispositivo alimentado por bateria, certifique-se de que ele esteja ativo e aceitando comandos ao usar esse serviço.", + "updateDeviceName": "Definir um nome personalizado para este dispositivo no registro do dispositivo.", + "remove": "Remova um dispositivo da rede ZigBee." + }, + "device_card": { + "device_name_placeholder": "Nome dado pelo usuário", + "area_picker_label": "Área", + "update_name_button": "Atualizar nome" + }, + "add_device_page": { + "header": "Zigbee Home Automation - Adicionar dispositivos", + "spinner": "Procurando por dispositivos ZHA Zigbee ...", + "discovery_text": "Dispositivos descobertos serão exibidos aqui. Siga as instruções para o(s) seu(s) dispositivo(s) e coloque o(s) dispositivo(s) no modo de emparelhamento." } }, "area_registry": { + "caption": "Área de Registro", "description": "Visão geral de todas as áreas de sua casa.", + "picker": { + "header": "Registro de Área", + "introduction": "Áreas são usadas para organizar os dispositivos. Essas informações serão usadas no Home Assistant para ajudá-lo a organizar sua interface, permissões e integrações com outros sistemas.", + "introduction2": "Para colocar dispositivos em uma área, use o link abaixo para navegar até a página de integrações e, em seguida, clique em uma integração configurada para acessar os cartões de dispositivos.", + "integrations_page": "Página de integrações", + "no_areas": "Parece que você ainda não tem áreas!", + "create_area": "CRIAR ÁREA" + }, "no_areas": "Parece que você ainda não tem áreas!", "create_area": "CRIAR ÁREA", "editor": { @@ -603,14 +665,16 @@ "delete": "APAGAR", "update": "ATUALIZAR", "create": "CRIAR" - }, - "picker": { - "integrations_page": "Página de integrações" } }, "entity_registry": { + "caption": "Registro de Entidade", + "description": "Visão geral de todas as entidades conhecidas.", "picker": { + "header": "Registro de Entidade", "unavailable": "(indisponível)", + "introduction": "O Home Assistant mantém um registro de todas as entidades que já viu e que podem ser identificadas exclusivamente. Cada uma dessas entidades terá um ID de entidade atribuído, que será reservado apenas para essa entidade.", + "introduction2": "Use o registro da entidade para substituir o nome, alterar o ID da entidade ou remover a entrada do Assistente Inicial. Observe que a remoção da entrada do registro de entidade não removerá a entidade. Para fazer isso, siga o link abaixo e remova-o da página de integrações.", "integrations_page": "Página de integrações" }, "editor": { @@ -625,14 +689,16 @@ "description": "Gerencie as pessoas que o Home Assistant acompanha.", "detail": { "name": "Nome", - "device_tracker_intro": "Selecione os dispositivos que pertencem a essa pessoa." + "device_tracker_intro": "Selecione os dispositivos que pertencem a essa pessoa.", + "device_tracker_picked": "Rastrear dispositivo", + "device_tracker_pick": "Escolha o dispositivo para rastrear" } } }, "profile": { "push_notifications": { "header": "Notificações push", - "description": "Enviar notificações para este dispositivo", + "description": "Envie notificações para este dispositivo.", "error_load_platform": "Configure o notify.html5.", "error_use_https": "Requer SSL habilitado para o frontend.", "push_notifications": "Notificações push", @@ -771,6 +837,24 @@ } }, "command_line": { + "step": { + "init": { + "data": { + "username": "Usuário", + "password": "Senha" + } + }, + "mfa": { + "data": { + "code": "Duplo fator de Autenticação" + }, + "description": "Abra o **{mfa_module_name}** no seu dispositivo para ver o seu código do duplo fator de autenticação e verifique sua identidade:" + } + }, + "error": { + "invalid_auth": "Usuário inválido ou senha", + "invalid_code": "Código de autenticação inválido" + }, "abort": { "login_expired": "Sessão expirada, por favor fazer o login novamente." } @@ -786,12 +870,27 @@ "data": { "name": "Nome", "username": "Usuário", - "password": "Senha" + "password": "Senha", + "password_confirm": "Confirme a Senha" }, "create_account": "Criar Conta", "error": { - "required_fields": "Preencha todos os campos obrigatórios" + "required_fields": "Preencha todos os campos obrigatórios", + "password_not_match": "As senhas não correspondem" } + }, + "integration": { + "intro": "Dispositivos e serviços são representados no Home Assistant como integrações. Você pode configurá-los agora ou fazê-lo mais tarde na tela de configuração.", + "more_integrations": "Mais", + "finish": "Terminar" + }, + "core-config": { + "intro": "Olá {name}, seja bem-vindo ao Home Assistant. Como você gostaria de nomear sua casa?", + "intro_location": "Nós gostaríamos de saber onde você mora. Essa informação ajudará na exibição de informações e na configuração de automações baseadas no sol. Esses dados nunca são compartilhados fora da sua rede.", + "intro_location_detect": "Podemos ajudá-lo a preencher essas informações fazendo uma solicitação única para um serviço externo.", + "location_name_default": "Casa", + "button_detect": "Detectar", + "finish": "Próximo" } }, "lovelace": { @@ -802,8 +901,17 @@ "add_item": "Adicionar item" }, "empty_state": { + "title": "Bem-vindo a casa", "no_devices": "Esta página permite que você controle seus dispositivos, no entanto, parece que você ainda não tem dispositivos configurados. Vá até a página de integrações para começar.", "go_to_integrations_page": "Vá para a página de integrações." + }, + "picture-elements": { + "hold": "Aguarde:", + "tap": "Toque:", + "navigate_to": "Navegue até {location}", + "toggle": "Alternar {name}", + "call_service": "Serviço de chamadas {name}", + "more_info": "Mostrar mais informações: {name}" } }, "editor": { @@ -837,6 +945,9 @@ "cancel": "Nunca", "save": "Assuma o controle" }, + "menu": { + "raw_editor": "Editor de configuração RAW" + }, "raw_editor": { "header": "Editar Configuração", "save": "Salvar", @@ -851,13 +962,20 @@ "refresh": "Atualizar" }, "warning": { - "entity_not_found": "Entidade não disponível: {entity}" - } + "entity_not_found": "Entidade não disponível: {entity}", + "entity_non_numeric": "Entidade não é numérica: {entity}" + }, + "changed_toast": { + "message": "A configuração do Lovelace foi atualizada, você gostaria de atualizar?", + "refresh": "Atualizar" + }, + "reload_lovelace": "Recarregar Lovelace" } }, "sidebar": { "log_out": "Sair", - "developer_tools": "Ferramentas do desenvolvedor" + "developer_tools": "Ferramentas do desenvolvedor", + "external_app_configuration": "Configuração do aplicativo" }, "common": { "loading": "Carregando", @@ -865,9 +983,9 @@ "save": "Salvar" }, "duration": { - "day": "{count} {count, plural,\none {dia}\nother {dias}\n}", + "day": "{count} {count, plural,\none {day}\nother {days}\n}", "week": "{count} {count, plural,\none {semana}\nother {semanas}\n}", - "second": "{count} {count, plural,\none {segundo}\nother {segundos}\n}", + "second": "{count} {count, plural,\none {second}\nother {seconds}\n}", "minute": "{count} {count, plural,\none {minuto}\nother {minutos}\n}", "hour": "{count} {count, plural,\none {hora}\nother {horas}\n}" }, @@ -924,7 +1042,8 @@ "arm_home": "Armar em casa", "arm_away": "Armar ausente", "arm_night": "Acionamento noturno", - "armed_custom_bypass": "Atalho personalizado" + "armed_custom_bypass": "Atalho personalizado", + "arm_custom_bypass": "Bypass personalizado" }, "automation": { "last_triggered": "Último disparo", @@ -1011,7 +1130,7 @@ }, "notification_toast": { "entity_turned_on": "{entity} ligado(a).", - "entity_turned_off": "{entity} desligado(a).", + "entity_turned_off": "Desativado {entity}", "service_called": "Serviço {service} chamado.", "service_call_failed": "Falha ao chamar o serviço {service}.", "connection_lost": "Conexão perdida. Reconectando…" @@ -1019,13 +1138,18 @@ "dialogs": { "more_info_settings": { "save": "Salvar", - "name": "Nome", + "name": "Substituição de nome", "entity_id": "ID da entidade" }, "more_info_control": { "script": { "last_action": "Última Ação" }, + "sun": { + "elevation": "Elevação", + "rising": "Aumentar", + "setting": "Configuração" + }, "updater": { "title": "Atualizar Instruções" } @@ -1079,8 +1203,10 @@ "weblink": "Weblink", "zwave": "", "vacuum": "Aspirando", + "zha": "ZHA", "hassio": "Hass.io", "homeassistant": "Home Assistant", + "lovelace": "Lovelace", "system_health": "Integridade Do Sistema", "person": "Pessoa" }, @@ -1090,5 +1216,19 @@ "visibility": "Visibilidade", "wind_speed": "Velocidade do vento" } + }, + "state_attributes": { + "climate": { + "fan_mode": { + "off": "Desligado", + "on": "Ligado", + "auto": "Auto" + } + } + }, + "groups": { + "system-admin": "Administradores", + "system-users": "Usuários", + "system-read-only": "Usuários somente leitura" } } \ No newline at end of file diff --git a/translations/sv.json b/translations/sv.json index 733d41401e..d718f6a329 100644 --- a/translations/sv.json +++ b/translations/sv.json @@ -964,7 +964,12 @@ "warning": { "entity_not_found": "Enheten är ej tillgänglig: {entity}", "entity_non_numeric": "Enheten är icke-numerisk: {entity}" - } + }, + "changed_toast": { + "message": "Lovelace-konfigurationen uppdaterades, vill du ladda om?", + "refresh": "Uppdatera" + }, + "reload_lovelace": "Uppdatera Lovelace" } }, "sidebar": { From 032ebce0bcd054cfbf326ee7f8faaed665aa08c1 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 4 Jun 2019 08:48:41 -0700 Subject: [PATCH 4/4] Bumped version to 20190604.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 34f56552d2..c3d29c54d3 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20190602.0", + version="20190604.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors",