Merge pull request #2649 from home-assistant/dev

20190201.0
This commit is contained in:
Paulus Schoutsen 2019-02-01 12:26:33 -08:00 committed by GitHub
commit bfee69e7ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 475 additions and 260 deletions

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
version="20190130.1",
version="20190201.0",
description="The Home Assistant frontend",
url="https://github.com/home-assistant/home-assistant-polymer",
author="The Home Assistant Authors",

View File

@ -365,18 +365,12 @@ class HaWeatherCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
computeDate(data) {
const date = new Date(data);
return date.toLocaleDateString(
this.hass.selectedLanguage || this.hass.language,
{ weekday: "short" }
);
return date.toLocaleDateString(this.hass.language, { weekday: "short" });
}
computeTime(data) {
const date = new Date(data);
return date.toLocaleTimeString(
this.hass.selectedLanguage || this.hass.language,
{ hour: "numeric" }
);
return date.toLocaleTimeString(this.hass.language, { hour: "numeric" });
}
_computeRTL(hass) {

View File

@ -7,3 +7,7 @@ export function computeRTL(hass: HomeAssistant) {
}
return false;
}
export function computeRTLDirection(hass: HomeAssistant) {
return computeRTL(hass) ? "rtl" : "ltr";
}

View File

@ -17,6 +17,7 @@ import "./ha-icon";
import isComponentLoaded from "../common/config/is_component_loaded";
import { HomeAssistant, Panel } from "../types";
import { fireEvent } from "../common/dom/fire_event";
import { DEFAULT_PANEL } from "../common/const";
const computeInitials = (name: string) => {
if (!name) {
@ -82,7 +83,12 @@ const computePanels = (hass: HomeAssistant) => {
*/
class HaSidebar extends LitElement {
public hass?: HomeAssistant;
public defaultPage?: string;
public _defaultPage?: string;
constructor() {
super();
this._defaultPage = localStorage.defaultPage || DEFAULT_PANEL;
}
protected render() {
const hass = this.hass;
@ -114,8 +120,8 @@ class HaSidebar extends LitElement {
<paper-listbox attr-for-selected="data-panel" .selected=${hass.panelUrl}>
<a
href="${computeUrl(this.defaultPage)}"
data-panel=${this.defaultPage}
href="${computeUrl(this._defaultPage)}"
data-panel=${this._defaultPage}
tabindex="-1"
>
<paper-icon-item>
@ -214,7 +220,7 @@ class HaSidebar extends LitElement {
static get properties(): PropertyDeclarations {
return {
hass: {},
defaultPage: {},
_defaultPage: {},
};
}

View File

@ -190,7 +190,7 @@ class StateHistoryChartTimeline extends LocalizeMixin(PolymerElement) {
yaxe.maxWidth = yaxe.chart.width * 0.18;
},
position: this.hass.translationMetadata.translations[
this.hass.selectedLanguage || this.hass.language
this.hass.language
].isRTL
? "right"
: "left",

View File

@ -1,17 +1,18 @@
import { HomeAssistant } from "../types";
export interface HomeAssistantSystemHealthInfo {
version: string;
dev: boolean;
hassio: boolean;
virtualenv: string;
python_version: string;
docker: boolean;
arch: string;
timezone: string;
os_name: string;
}
export interface SystemHealthInfo {
homeassistant: {
version: string;
dev: boolean;
hassio: boolean;
virtualenv: string;
python_version: string;
docker: boolean;
arch: string;
timezone: string;
os_name: string;
};
[domain: string]: { [key: string]: string | number | boolean };
}

View File

@ -178,20 +178,18 @@ class MoreInfoWeather extends LocalizeMixin(PolymerElement) {
provider === "Data provided by OpenWeatherMap"
) {
if (new Date().getDay() === date.getDay()) {
return date.toLocaleTimeString(
this.hass.selectedLanguage || this.hass.language,
{ hour: "numeric" }
);
return date.toLocaleTimeString(this.hass.language, { hour: "numeric" });
}
return date.toLocaleDateString(
this.hass.selectedLanguage || this.hass.language,
{ weekday: "long", hour: "numeric" }
);
return date.toLocaleDateString(this.hass.language, {
weekday: "long",
hour: "numeric",
});
}
return date.toLocaleDateString(
this.hass.selectedLanguage || this.hass.language,
{ weekday: "long", month: "short", day: "numeric" }
);
return date.toLocaleDateString(this.hass.language, {
weekday: "long",
month: "short",
day: "numeric",
});
}
getUnit(measure) {

View File

@ -74,8 +74,8 @@ export const dialogManagerMixin = (
if (!(dialogTag in LOADED)) {
LOADED[dialogTag] = dialogImport().then(() => {
const dialogEl = document.createElement(dialogTag) as HassDialog;
this.shadowRoot!.appendChild(dialogEl);
this.provideHass(dialogEl);
this.shadowRoot!.appendChild(dialogEl);
return dialogEl;
});
}

View File

@ -1,16 +0,0 @@
import { storeState } from "../../util/ha-pref-storage";
export default (superClass) =>
class extends superClass {
firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this.addEventListener("hass-dock-sidebar", (e) =>
this._handleDockSidebar(e)
);
}
_handleDockSidebar(ev) {
this._updateHass({ dockedSidebar: ev.detail.dock });
storeState(this.hass);
}
};

View File

@ -0,0 +1,30 @@
import { storeState } from "../../util/ha-pref-storage";
import { Constructor, LitElement } from "lit-element";
import { HassBaseEl } from "./hass-base-mixin";
import { HASSDomEvent } from "../../common/dom/fire_event";
interface DockSidebarParams {
dock: boolean;
}
declare global {
// for fire event
interface HASSDomEvents {
"hass-dock-sidebar": DockSidebarParams;
}
// for add event listener
interface HTMLElementEventMap {
"hass-dock-sidebar": HASSDomEvent<DockSidebarParams>;
}
}
export default (superClass: Constructor<LitElement & HassBaseEl>) =>
class extends superClass {
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
this.addEventListener("hass-dock-sidebar", (ev) => {
this._updateHass({ dockedSidebar: ev.detail.dock });
storeState(this.hass);
});
}
};

View File

@ -4,6 +4,8 @@ import { storeState } from "../../util/ha-pref-storage";
import { Constructor, LitElement } from "lit-element";
import { HassBaseEl } from "./hass-base-mixin";
import { computeLocalize } from "../../common/translations/localize";
import { computeRTL } from "../../common/util/compute_rtl";
import { HomeAssistant } from "../../types";
/*
* superClass needs to contain `this.hass` and `this._updateHass`.
@ -22,6 +24,7 @@ export default (superClass: Constructor<LitElement & HassBaseEl>) =>
protected hassConnected() {
super.hassConnected();
this._loadBackendTranslations();
this.style.direction = computeRTL(this.hass!) ? "rtl" : "ltr";
}
protected hassReconnected() {
@ -79,15 +82,17 @@ export default (superClass: Constructor<LitElement & HassBaseEl>) =>
...data,
},
};
this._updateHass({
language,
resources,
localize: computeLocalize(this, language, resources),
});
const changes: Partial<HomeAssistant> = { resources };
if (language === this.hass!.language) {
changes.localize = computeLocalize(this, language, resources);
}
this._updateHass(changes);
}
private _selectLanguage(event) {
this._updateHass({ selectedLanguage: event.detail.language });
const language: string = event.detail.language;
this._updateHass({ language, selectedLanguage: language });
this.style.direction = computeRTL(this.hass!) ? "rtl" : "ltr";
storeState(this.hass);
this._loadResources();
this._loadBackendTranslations();

View File

@ -1,152 +0,0 @@
import "@polymer/app-layout/app-drawer-layout/app-drawer-layout";
import "@polymer/app-layout/app-drawer/app-drawer";
import "@polymer/app-route/app-route";
import "@polymer/iron-media-query/iron-media-query";
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../util/ha-url-sync";
import "./partial-panel-resolver";
import EventsMixin from "../mixins/events-mixin";
import NavigateMixin from "../mixins/navigate-mixin";
import { computeRTL } from "../common/util/compute_rtl";
import { DEFAULT_PANEL } from "../common/const";
import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar");
import(/* webpackChunkName: "voice-command-dialog" */ "../dialogs/ha-voice-command-dialog");
const NON_SWIPABLE_PANELS = ["kiosk", "map"];
class HomeAssistantMain extends NavigateMixin(EventsMixin(PolymerElement)) {
static get template() {
return html`
<style>
:host {
color: var(--primary-text-color);
/* remove the grey tap highlights in iOS on the fullscreen touch targets */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
:host([rtl]) {
direction: rtl;
}
partial-panel-resolver,
ha-sidebar {
/* allow a light tap highlight on the actual interface elements */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
}
partial-panel-resolver {
height: 100%;
}
</style>
<ha-url-sync hass="[[hass]]"></ha-url-sync>
<ha-voice-command-dialog
hass="[[hass]]"
id="voiceDialog"
></ha-voice-command-dialog>
<iron-media-query query="(max-width: 870px)" query-matches="{{narrow}}">
</iron-media-query>
<app-drawer-layout
fullbleed=""
force-narrow="[[computeForceNarrow(narrow, dockedSidebar)]]"
responsive-width="0"
>
<app-drawer
id="drawer"
align="start"
slot="drawer"
disable-swipe="[[_computeDisableSwipe(hass)]]"
swipe-open="[[!_computeDisableSwipe(hass)]]"
persistent="[[dockedSidebar]]"
>
<ha-sidebar
hass="[[hass]]"
default-page="[[_defaultPage]]"
></ha-sidebar>
</app-drawer>
<partial-panel-resolver
narrow="[[narrow]]"
hass="[[hass]]"
route="[[route]]"
show-menu="[[dockedSidebar]]"
></partial-panel-resolver>
</app-drawer-layout>
`;
}
static get properties() {
return {
hass: Object,
narrow: Boolean,
route: {
type: Object,
observer: "_routeChanged",
},
dockedSidebar: {
type: Boolean,
computed: "computeDockedSidebar(hass)",
},
rtl: {
type: Boolean,
reflectToAttribute: true,
computed: "_computeRTL(hass)",
},
};
}
ready() {
super.ready();
this._defaultPage = localStorage.defaultPage || DEFAULT_PANEL;
this.addEventListener("hass-open-menu", () => this.handleOpenMenu());
this.addEventListener("hass-close-menu", () => this.handleCloseMenu());
this.addEventListener("hass-start-voice", (ev) =>
this.handleStartVoice(ev)
);
}
_routeChanged() {
if (this.narrow) {
this.$.drawer.close();
}
}
handleStartVoice(ev) {
ev.stopPropagation();
this.$.voiceDialog.opened = true;
}
handleOpenMenu() {
if (this.narrow) {
this.$.drawer.open();
} else {
this.fire("hass-dock-sidebar", { dock: true });
}
}
handleCloseMenu() {
this.$.drawer.close();
if (this.dockedSidebar) {
this.fire("hass-dock-sidebar", { dock: false });
}
}
computeForceNarrow(narrow, dockedSidebar) {
return narrow || !dockedSidebar;
}
computeDockedSidebar(hass) {
return hass.dockedSidebar;
}
_computeDisableSwipe(hass) {
return NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
}
_computeRTL(hass) {
return computeRTL(hass);
}
}
customElements.define("home-assistant-main", HomeAssistantMain);

View File

@ -0,0 +1,151 @@
import {
LitElement,
html,
TemplateResult,
PropertyDeclarations,
CSSResult,
css,
PropertyValues,
} from "lit-element";
import "@polymer/app-layout/app-drawer-layout/app-drawer-layout";
import "@polymer/app-layout/app-drawer/app-drawer";
// Not a duplicate, it's for typing
// tslint:disable-next-line
import { AppDrawerElement } from "@polymer/app-layout/app-drawer/app-drawer";
import "@polymer/app-route/app-route";
import "@polymer/iron-media-query/iron-media-query";
import "../util/ha-url-sync";
import "./partial-panel-resolver";
import { HomeAssistant, Route } from "../types";
import { fireEvent } from "../common/dom/fire_event";
import { PolymerChangedEvent } from "../polymer-types";
import(/* webpackChunkName: "ha-sidebar" */ "../components/ha-sidebar");
import(/* webpackChunkName: "voice-command-dialog" */ "../dialogs/ha-voice-command-dialog");
const NON_SWIPABLE_PANELS = ["kiosk", "map"];
class HomeAssistantMain extends LitElement {
public hass?: HomeAssistant;
public route?: Route;
private _narrow?: boolean;
static get properties(): PropertyDeclarations {
return {
hass: {},
narrow: {},
route: {},
};
}
protected render(): TemplateResult | void {
const hass = this.hass;
if (!hass) {
return;
}
const disableSwipe = NON_SWIPABLE_PANELS.indexOf(hass.panelUrl) !== -1;
return html`
<ha-url-sync .hass=${hass}></ha-url-sync>
<ha-voice-command-dialog .hass=${hass}></ha-voice-command-dialog>
<iron-media-query
query="(max-width: 870px)"
query-matches-changed=${this._narrowChanged}
></iron-media-query>
<app-drawer-layout
fullbleed
.forceNarrow=${this._narrow || !hass.dockedSidebar}
responsive-width="0"
>
<app-drawer
id="drawer"
align="start"
slot="drawer"
.disableSwipe=${disableSwipe}
.swipeOpen=${!disableSwipe}
.persistent=${hass.dockedSidebar}
>
<ha-sidebar .hass=${hass}></ha-sidebar>
</app-drawer>
<partial-panel-resolver
.narrow=${this._narrow}
.hass=${hass}
.route=${this.route}
.showMenu=${hass.dockedSidebar}
></partial-panel-resolver>
</app-drawer-layout>
`;
}
protected firstUpdated() {
this.addEventListener("hass-open-menu", () => {
if (this._narrow) {
this.drawer.open();
} else {
fireEvent(this, "hass-dock-sidebar", { dock: true });
}
});
this.addEventListener("hass-close-menu", () => {
this.drawer.close();
if (this.hass!.dockedSidebar) {
fireEvent(this, "hass-dock-sidebar", { dock: false });
}
});
this.addEventListener("hass-start-voice", () => {
(this.voiceDialog as any).opened = true;
});
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
if (changedProps.has("route") && this._narrow) {
this.drawer.close();
}
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
// Make app-drawer adjust to a potential LTR/RTL change
if (oldHass && oldHass.language !== this.hass!.language) {
this.drawer._resetPosition();
}
}
private _narrowChanged(ev: PolymerChangedEvent<boolean>) {
this._narrow = ev.detail.value;
}
private get drawer(): AppDrawerElement {
return this.shadowRoot!.querySelector("app-drawer")!;
}
private get voiceDialog() {
return this.shadowRoot!.querySelector("ha-voice-command-dialog")!;
}
static get styles(): CSSResult {
return css`
:host {
color: var(--primary-text-color);
/* remove the grey tap highlights in iOS on the fullscreen touch targets */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
partial-panel-resolver,
ha-sidebar {
/* allow a light tap highlight on the actual interface elements */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
}
partial-panel-resolver {
height: 100%;
}
`;
}
}
customElements.define("home-assistant-main", HomeAssistantMain);

View File

@ -2,6 +2,7 @@ import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import LocalizeMixin from "../mixins/localize-mixin";
import { computeRTL } from "../common/util/compute_rtl";
class NotificationManager extends LocalizeMixin(PolymerElement) {
static get template() {
@ -14,6 +15,7 @@ class NotificationManager extends LocalizeMixin(PolymerElement) {
<ha-toast
id="toast"
dir="[[_rtl]]"
no-cancel-on-outside-click="[[_cancelOnOutsideClick]]"
></ha-toast>
`;
@ -27,6 +29,11 @@ class NotificationManager extends LocalizeMixin(PolymerElement) {
type: Boolean,
value: false,
},
_rtl: {
type: String,
computed: "_computeRTLDirection(hass)",
},
};
}
@ -38,6 +45,10 @@ class NotificationManager extends LocalizeMixin(PolymerElement) {
showDialog({ message }) {
this.$.toast.show(message);
}
_computeRTLDirection(hass) {
return computeRTL(hass) ? "rtl" : "ltr";
}
}
customElements.define("notification-manager", NotificationManager);

View File

@ -97,6 +97,7 @@ class DialogAreaDetail extends LitElement {
}
private async _updateEntry() {
this._submitting = true;
try {
const values: AreaRegistryEntryMutableParams = {
name: this._name.trim(),
@ -109,12 +110,19 @@ class DialogAreaDetail extends LitElement {
this._params = undefined;
} catch (err) {
this._error = err;
} finally {
this._submitting = false;
}
}
private async _deleteEntry() {
if (await this._params!.removeEntry()) {
this._params = undefined;
this._submitting = true;
try {
if (await this._params!.removeEntry()) {
this._params = undefined;
}
} finally {
this._submitting = false;
}
}

View File

@ -162,7 +162,6 @@ All devices in this area will become unassigned.`)
display: block;
max-width: 600px;
margin: 16px auto;
background-color: white;
}
.empty {
text-align: center;

View File

@ -145,7 +145,7 @@ class HaConfigEntries extends NavigateMixin(PolymerElement) {
});
fetchAreaRegistry(this.hass).then((areas) => {
this._areas = areas;
this._areas = areas.sort((a, b) => compare(a.name, b.name));
});
}

View File

@ -123,25 +123,27 @@ class DialogEntityRegistryDetail extends LitElement {
}
private async _updateEntry(): Promise<void> {
this._submitting = true;
try {
this._submitting = true;
await this._params!.updateEntry({
name: this._name.trim() || null,
new_entity_id: this._entityId.trim(),
});
this._params = undefined;
} catch (err) {
this._submitting = false;
this._error = err;
} finally {
this._submitting = false;
}
}
private async _deleteEntry(): Promise<void> {
this._submitting = true;
if (await this._params!.removeEntry()) {
this._params = undefined;
} else {
try {
if (await this._params!.removeEntry()) {
this._params = undefined;
}
} finally {
this._submitting = false;
}
}

View File

@ -150,7 +150,6 @@ Deleting an entry will not remove the entity from Home Assistant. To do this, yo
}
paper-card {
display: block;
background-color: white;
}
paper-icon-item {
cursor: pointer;

View File

@ -95,7 +95,16 @@ class SystemHealthCard extends LitElement {
}
private async _fetchInfo() {
this._info = await fetchSystemHealthInfo(this.hass!);
try {
this._info = await fetchSystemHealthInfo(this.hass!);
} catch (err) {
this._info = {
system_health: {
error:
"System Health component is not loaded. Add 'system_health:' to configuration.yaml",
},
};
}
}
static get styles(): CSSResult {

View File

@ -9,9 +9,11 @@ import {
html,
css,
CSSResult,
PropertyValues,
} from "lit-element";
import { HomeAssistant } from "../../../types";
import { EntitiesCardEntityConfig } from "../cards/hui-entities-card";
import { computeRTL } from "../../../common/util/compute_rtl";
class HuiGenericEntityRow extends LitElement {
public hass?: HomeAssistant;
@ -76,6 +78,13 @@ class HuiGenericEntityRow extends LitElement {
};
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
if (changedProps.has("hass")) {
this.toggleAttribute("rtl", computeRTL(this.hass!));
}
}
static get styles(): CSSResult {
return css`
:host {
@ -119,6 +128,14 @@ class HuiGenericEntityRow extends LitElement {
state-badge {
flex: 0 0 40px;
}
:host([rtl]) .flex {
margin-left: 0;
margin-right: 16px;
}
:host([rtl]) .flex ::slotted(*) {
margin-left: 0;
margin-right: 8px;
}
`;
}
}

View File

@ -9,15 +9,20 @@ import { LovelaceCard } from "../../types";
import { ConfigError } from "../types";
import { getCardElementTag } from "../../common/get-card-element-tag";
import { createErrorCardConfig } from "../../cards/hui-error-card";
import { computeRTL } from "../../../../common/util/compute_rtl";
export class HuiCardPreview extends HTMLElement {
private _hass?: HomeAssistant;
private _element?: LovelaceCard;
set hass(value: HomeAssistant) {
this._hass = value;
set hass(hass: HomeAssistant) {
if (!this._hass || this._hass.language !== hass.language) {
this.style.direction = computeRTL(hass) ? "rtl" : "ltr";
}
this._hass = hass;
if (this._element) {
this._element.hass = value;
this._element.hass = hass;
}
}

View File

@ -99,6 +99,7 @@ class LovelaceFullConfigEditor extends LitElement {
.content {
height: calc(100vh - 68px);
direction: ltr;
}
hui-code-editor {

View File

@ -21,6 +21,12 @@ class HaPickLanguageRow extends LocalizeMixin(EventsMixin(PolymerElement)) {
a {
color: var(--primary-color);
}
paper-item {
direction: ltr;
}
paper-item[is-rtl] {
direction: rtl;
}
</style>
<ha-settings-row narrow="[[narrow]]">
<span slot="heading"
@ -43,9 +49,9 @@ class HaPickLanguageRow extends LocalizeMixin(EventsMixin(PolymerElement)) {
selected="{{languageSelection}}"
>
<template is="dom-repeat" items="[[languages]]">
<paper-item language-tag$="[[item.tag]]"
>[[item.nativeName]]</paper-item
>
<paper-item language-tag$="[[item.key]]" is-rtl$="[[item.isRTL]]">
[[item.nativeName]]
</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
@ -76,9 +82,10 @@ class HaPickLanguageRow extends LocalizeMixin(EventsMixin(PolymerElement)) {
if (!hass || !hass.translationMetadata) {
return [];
}
return Object.keys(hass.translationMetadata.translations).map((key) => ({
tag: key,
nativeName: hass.translationMetadata.translations[key].nativeName,
const translations = hass.translationMetadata.translations;
return Object.keys(translations).map((key) => ({
key,
...translations[key],
}));
}

View File

@ -35,6 +35,7 @@
"sensor": "Sensor",
"sun": "Sun",
"switch": "Switch",
"system_health": "System Health",
"updater": "Updater",
"vacuum": "Vacuum",
"weblink": "Weblink",

View File

@ -826,7 +826,7 @@
"code": "Kód",
"clear_code": "Zrušit",
"disarm": "Deaktivovat",
"arm_home": "Aktivní doma",
"arm_home": "Aktivovat domov",
"arm_away": "Aktivní v nepřítomnosti",
"arm_night": "Aktivní v noci",
"armed_custom_bypass": "Specifické obejítí alarmu"

View File

@ -433,6 +433,14 @@
"hours": "Hours",
"minutes": "Minutes",
"seconds": "Seconds"
},
"geo_location": {
"label": "Geolocation",
"source": "Source",
"zone": "Zone",
"event": "Event:",
"enter": "Enter",
"leave": "Leave"
}
}
},
@ -565,7 +573,18 @@
},
"zha": {
"caption": "ZHA",
"description": "Zigbee Home Automation network management"
"description": "Zigbee Home Automation network management",
"services": {
"reconfigure": "Reconfigure ZHA device (heal device). Use this if you are having issues with the device. If the device in question is a battery powered device please ensure it is awake and accepting commands when you use this service."
}
},
"area_registry": {
"caption": "Area Registry",
"description": "Overview of all areas in your home."
},
"entity_registry": {
"caption": "Entity Registry",
"description": "Overview of all known entities."
}
},
"profile": {
@ -734,6 +753,11 @@
"checked_items": "Checked items",
"clear_items": "Clear checked items",
"add_item": "Add item"
},
"empty_state": {
"title": "Welcome Home",
"no_devices": "This page allows you to control your devices, however it looks like you have no devices set up yet. Head to the integrations page to get started.",
"go_to_integrations_page": "Go to the integrations page."
}
},
"editor": {
@ -934,7 +958,7 @@
"dialogs": {
"more_info_settings": {
"save": "Save",
"name": "Name",
"name": "Name Override",
"entity_id": "Entity ID"
},
"more_info_control": {
@ -999,7 +1023,10 @@
"weblink": "Weblink",
"zwave": "Z-Wave",
"vacuum": "Vacuum",
"zha": "ZHA"
"zha": "ZHA",
"hassio": "Hass.io",
"homeassistant": "Home Assistant",
"lovelace": "Lovelace"
},
"attribute": {
"weather": {

View File

@ -433,6 +433,14 @@
"hours": "Stonnen",
"minutes": "Minutten",
"seconds": "Sekonnen"
},
"geo_location": {
"label": "Geolokalisatioun",
"source": "Quell",
"zone": "Zone",
"event": "Evenement",
"enter": "Betrieden",
"leave": "Verloossen"
}
}
},
@ -565,7 +573,18 @@
},
"zha": {
"caption": "ZHA",
"description": "Gestioun vum Zigbee Home Automation Reseau"
"description": "Gestioun vum Zigbee Home Automation Reseau",
"services": {
"reconfigure": "ZHA Apparat rekonfiguréieren (Apparat heelen). Benotzt dëst am Fall vu Problemer mam Apparat. Falls den Apparat duerch eng Batterie gespeist gëtt stellt sécher dass en un ass a Befeeler entgéint kann huelen"
}
},
"area_registry": {
"caption": "Lëscht vun de Beräicher",
"description": "Iwwersiicht vun de Beräicher am Haus"
},
"entity_registry": {
"caption": "Lëscht vun den Entitéiten",
"description": "Iwwersiicht vun all bekannten Entitéiten."
}
},
"profile": {
@ -589,28 +608,28 @@
"dropdown_label": "Thema"
},
"refresh_tokens": {
"header": "Token erneieren",
"description": "All Sessioun Token representéiert eng Login Sessioun. Sessioun's Token ginn automatesch gelëscht wann dir op auslogge klickt. Folgend Sessioun's Token si fir de Moment fir Ären Account aktiv.",
"token_title": "Token erneiren fir {clientId}",
"header": "Jeton erneieren",
"description": "All Sessioun's Jeton representéiert eng Login Sessioun. Sessioun's Jetone ginn automatesch geläscht wann dir op auslogge klickt. Folgend Sessioun's Jetone si fir de Moment fir Ären Account aktiv.",
"token_title": "Jeton erneiren fir {clientId}",
"created_at": "Erstallt um {date}",
"confirm_delete": "Sécher fir den Erneierungs Token fir {name} ze läsche?",
"delete_failed": "Fehler beim läschen vum Erneierungs Token",
"confirm_delete": "Sécher fir den Erneierungs Jeton fir {name} ze läsche?",
"delete_failed": "Fehler beim läschen vum Erneierungs Jeton.",
"last_used": "Fir d'Läscht benotzt um {date} vun {location}",
"not_used": "Nach nie benotzt ginn",
"current_token_tooltip": "Fehler beim läschen vum aktuellen Erneierungs Token"
"current_token_tooltip": "Fehler beim läschen vum aktuellen Erneierungs Jeton"
},
"long_lived_access_tokens": {
"header": "Lang gëlteg Access Token",
"description": "Erstellt laang gëlteg Access Token déi et äre Skripten erlabe mat ärem Home Assistant z'interagéieren. All eenzelen Token ass gëlteg fir 10 Joer. Folgend Access Token sinn am Moment aktiv.",
"header": "Lang gëlteg Accèss Jetone",
"description": "Erstellt laang gëlteg Accèss Jetone déi et äre Skripten erlabe mat ärem Home Assistant z'interagéieren. All eenzelen Jeton ass gëlteg fir 10 Joer. Folgend Accèss Jeton sinn am Moment aktiv.",
"learn_auth_requests": "Leiert wéi een \"authenticated requests\" erstellt.",
"created_at": "Erstallt um {date}",
"confirm_delete": "Sécher fir den Access Token fir {name} ze läsche?",
"delete_failed": "Fehler beim läschen vum Access Token",
"create": "Token erstellen",
"create_failed": "Fehler beim erstellen vum Access Token",
"confirm_delete": "Sécher fir den Accèss Jeton fir {name} ze läsche?",
"delete_failed": "Fehler beim läschen vum Accèss Jeton",
"create": "Jeton erstellen",
"create_failed": "Fehler beim erstellen vum Accèss Jeton",
"prompt_name": "Numm?",
"prompt_copy_token": "Kopéiert den Access Token. E gëtt nie méi ugewisen.",
"empty_state": "Et ginn nach keng laang gëlteg Access Token.",
"prompt_copy_token": "Kopéiert den Accèss Jeton. E gëtt nie méi ugewisen.",
"empty_state": "Et ginn nach keng laang gëlteg Accèss Jeton.",
"last_used": "Fir d'Läscht benotzt um {date} vun {location}",
"not_used": "Nach nie benotzt ginn"
},
@ -734,6 +753,11 @@
"checked_items": "Markéiert Elementer",
"clear_items": "Markéiert Elementer läschen",
"add_item": "Element dobäisetzen"
},
"empty_state": {
"title": "Wëllkomm Doheem",
"no_devices": "Dës Säit erlaabt et iech är Apparater ze kontrolléiere, awer wéi et schéngt sinn nach keng Apparater ageriicht. Gitt op d'Integratioun's Säit fir unzefänken.",
"go_to_integrations_page": "Zur Integratiouns Säit goen"
}
},
"editor": {
@ -999,7 +1023,10 @@
"weblink": "Weblink",
"zwave": "Z-Wave",
"vacuum": "Staubsauger",
"zha": "ZHA"
"zha": "ZHA",
"hassio": "Hass.io",
"homeassistant": "Home Assistant",
"lovelace": "Lovelace"
},
"attribute": {
"weather": {

View File

@ -433,6 +433,14 @@
"hours": "Godziny",
"minutes": "Minuty",
"seconds": "Sekundy"
},
"geo_location": {
"label": "Geolokalizacja",
"source": "Źródło",
"zone": "Strefa",
"event": "Zdarzenie:",
"enter": "wejście",
"leave": "wyjście"
}
}
},
@ -565,7 +573,18 @@
},
"zha": {
"caption": "ZHA",
"description": "Zarządzanie siecią ZigBee Home Automation"
"description": "Zarządzanie siecią ZigBee Home Automation",
"services": {
"reconfigure": "Ponowna konfiguracja urządzenia ZHA (uzdrawianie urządzenia). Użyj tej usługi, jeśli masz problemy z urządzeniem. Jeśli urządzenie jest zasilane bateryjnie, upewnij się, że nie jest uśpione i przyjmie polecenie rekonfiguracji."
}
},
"area_registry": {
"caption": "Rejestr lokalizacji",
"description": "Przegląd wszystkich lokalizacji w twoim domu."
},
"entity_registry": {
"caption": "Rejestr encji",
"description": "Przegląd wszystkich znanych encji"
}
},
"profile": {
@ -734,6 +753,11 @@
"checked_items": "Pozycje zaznaczone",
"clear_items": "Wyczyść zaznaczone pozycje",
"add_item": "Dodaj pozycję"
},
"empty_state": {
"title": "Witaj w domu",
"no_devices": "Ta strona pozwala kontrolować urządzenia, ale wygląda na to, że nie masz jeszcze żadnych skonfigurowanych. Przejdź na stronę integracji, aby rozpocząć.",
"go_to_integrations_page": "Przejdź do strony integracji."
}
},
"editor": {
@ -999,7 +1023,10 @@
"weblink": "Link",
"zwave": "Z-Wave",
"vacuum": "Odkurzacz",
"zha": "ZHA"
"zha": "ZHA",
"hassio": "Hass.io",
"homeassistant": "Home Assistant",
"lovelace": "Lovelace"
},
"attribute": {
"weather": {

View File

@ -433,6 +433,14 @@
"hours": "Часов",
"minutes": "Минут",
"seconds": "Секунд"
},
"geo_location": {
"label": "Геолокация",
"source": "Источник",
"zone": "Зона",
"event": "Событие:",
"enter": "Войти",
"leave": "Покинуть"
}
}
},
@ -565,7 +573,18 @@
},
"zha": {
"caption": "ZHA",
"description": "Управление сетью Zigbee Home Automation"
"description": "Управление сетью Zigbee Home Automation",
"services": {
"reconfigure": "Перенастройка устройства ZHA. Используйте эту службу, если у Вас есть проблемы с устройством. Если рассматриваемое устройство работает от батареи, пожалуйста, убедитесь, что оно не находится в режиме сна и принимает команды, когда вы запускаете эту службу."
}
},
"area_registry": {
"caption": "Управление зонами",
"description": "Обзор всех помещений и зон в Вашем доме"
},
"entity_registry": {
"caption": "Управление объектами",
"description": "Обзор всех доступных объектов"
}
},
"profile": {
@ -734,6 +753,11 @@
"checked_items": "Отмеченные элементы",
"clear_items": "Очистить отмеченные элементы",
"add_item": "Добавить элемент"
},
"empty_state": {
"title": "Добро пожаловать домой",
"no_devices": "Эта страница позволяет вам управлять вашими устройствами, однако, похоже, у вас еще нет настроенных устройств. Перейдите на страницу интеграций, чтобы начать.",
"go_to_integrations_page": "Перейти на страницу интеграций"
}
},
"editor": {
@ -999,7 +1023,10 @@
"weblink": "Интернет-ссылка",
"zwave": "Z-Wave",
"vacuum": "Пылесос",
"zha": "ZHA"
"zha": "ZHA",
"hassio": "Hass.io",
"homeassistant": "Home Assistant",
"lovelace": "Lovelace"
},
"attribute": {
"weather": {

View File

@ -433,6 +433,14 @@
"hours": "小時",
"minutes": "分鐘",
"seconds": "秒鐘"
},
"geo_location": {
"label": "地理位置",
"source": "來源",
"zone": "區域",
"event": "事件:",
"enter": "進入區域",
"leave": "離開區域"
}
}
},
@ -565,7 +573,18 @@
},
"zha": {
"caption": "ZHA",
"description": "Zigbee 家庭自動化網路管理"
"description": "Zigbee 家庭自動化網路管理",
"services": {
"reconfigure": "重新設定 ZHA Zibgee 裝置(健康裝置)。假如遇到裝置問題,請使用此選項。假如有問題的裝置為使用電池的裝置,請先確定裝置已喚醒並處於接受命令狀態。"
}
},
"area_registry": {
"caption": "區域 ID",
"description": "家中所有區域概觀。"
},
"entity_registry": {
"caption": "物件 ID",
"description": "所有已知物件概觀。"
}
},
"profile": {
@ -734,6 +753,11 @@
"checked_items": "已選取項目",
"clear_items": "清除已選取項目",
"add_item": "新增項目"
},
"empty_state": {
"title": "歡迎回家",
"no_devices": "此頁面允許進行控制所擁有的裝置。看起來您尚未設定任何裝置,從設定中的整合頁面開始吧。",
"go_to_integrations_page": "轉至整合頁面。"
}
},
"editor": {
@ -934,7 +958,7 @@
"dialogs": {
"more_info_settings": {
"save": "儲存",
"name": "名稱",
"name": "名稱撤銷",
"entity_id": "物件 ID"
},
"more_info_control": {
@ -999,7 +1023,10 @@
"weblink": "網站鏈接",
"zwave": "Z-Wave",
"vacuum": "吸塵器",
"zha": "ZHA"
"zha": "ZHA",
"hassio": "Hass.io",
"homeassistant": "Home Assistant",
"lovelace": "Lovelace"
},
"attribute": {
"weather": {