mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-02 14:07:55 +00:00
Merge pull request #6821 from home-assistant/dev
This commit is contained in:
commit
4999f1ad51
@ -88,8 +88,8 @@ class HassioAddonNetwork extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
<ha-progress-button class="warning" @click=${this._resetTapped}>
|
||||||
Reset to defaults </ha-progress-button
|
Reset to defaults
|
||||||
>>
|
</ha-progress-button>
|
||||||
<ha-progress-button @click=${this._saveTapped}>
|
<ha-progress-button @click=${this._saveTapped}>
|
||||||
Save
|
Save
|
||||||
</ha-progress-button>
|
</ha-progress-button>
|
||||||
|
@ -164,8 +164,9 @@ export class HassioUpdate extends LitElement {
|
|||||||
try {
|
try {
|
||||||
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
|
await this.hass.callApi<HassioResponse<void>>("POST", item.apiPath);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Only show an error if the status code was not 504, or no status at all (connection terminated)
|
// Only show an error if the status code was not expected (user behind proxy)
|
||||||
if (err.status_code && err.status_code !== 504) {
|
// or no status at all(connection terminated)
|
||||||
|
if (err.status_code && ![502, 503, 504].includes(err.status_code)) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Update failed",
|
title: "Update failed",
|
||||||
text: extractApiErrorMessage(err),
|
text: extractApiErrorMessage(err),
|
||||||
|
@ -18,6 +18,7 @@ import {
|
|||||||
setSupervisorOption,
|
setSupervisorOption,
|
||||||
SupervisorOptions,
|
SupervisorOptions,
|
||||||
updateSupervisor,
|
updateSupervisor,
|
||||||
|
fetchHassioSupervisorInfo,
|
||||||
} from "../../../src/data/hassio/supervisor";
|
} from "../../../src/data/hassio/supervisor";
|
||||||
import {
|
import {
|
||||||
showAlertDialog,
|
showAlertDialog,
|
||||||
@ -176,10 +177,11 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const data: Partial<SupervisorOptions> = {
|
const data: Partial<SupervisorOptions> = {
|
||||||
channel: this.supervisorInfo.channel !== "stable" ? "beta" : "stable",
|
channel: this.supervisorInfo.channel === "stable" ? "beta" : "stable",
|
||||||
};
|
};
|
||||||
await setSupervisorOption(this.hass, data);
|
await setSupervisorOption(this.hass, data);
|
||||||
await reloadSupervisor(this.hass);
|
await reloadSupervisor(this.hass);
|
||||||
|
this.supervisorInfo = await fetchHassioSupervisorInfo(this.hass);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Failed to set supervisor option",
|
title: "Failed to set supervisor option",
|
||||||
@ -195,6 +197,7 @@ class HassioSupervisorInfo extends LitElement {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await reloadSupervisor(this.hass);
|
await reloadSupervisor(this.hass);
|
||||||
|
this.supervisorInfo = await fetchHassioSupervisorInfo(this.hass);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showAlertDialog(this, {
|
showAlertDialog(this, {
|
||||||
title: "Failed to reload the supervisor",
|
title: "Failed to reload the supervisor",
|
||||||
|
@ -79,6 +79,7 @@
|
|||||||
"@polymer/polymer": "3.1.0",
|
"@polymer/polymer": "3.1.0",
|
||||||
"@thomasloven/round-slider": "0.5.0",
|
"@thomasloven/round-slider": "0.5.0",
|
||||||
"@types/chromecast-caf-sender": "^1.0.3",
|
"@types/chromecast-caf-sender": "^1.0.3",
|
||||||
|
"@types/sortablejs": "^1.10.6",
|
||||||
"@vaadin/vaadin-combo-box": "^5.0.10",
|
"@vaadin/vaadin-combo-box": "^5.0.10",
|
||||||
"@vaadin/vaadin-date-picker": "^4.0.7",
|
"@vaadin/vaadin-date-picker": "^4.0.7",
|
||||||
"@vue/web-component-wrapper": "^1.2.0",
|
"@vue/web-component-wrapper": "^1.2.0",
|
||||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="home-assistant-frontend",
|
name="home-assistant-frontend",
|
||||||
version="20200904.0",
|
version="20200907.0",
|
||||||
description="The Home Assistant frontend",
|
description="The Home Assistant frontend",
|
||||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||||
author="The Home Assistant Authors",
|
author="The Home Assistant Authors",
|
||||||
|
178
src/components/entity/ha-entity-attribute-picker.ts
Normal file
178
src/components/entity/ha-entity-attribute-picker.ts
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
|
import "@vaadin/vaadin-combo-box/theme/material/vaadin-combo-box-light";
|
||||||
|
import { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
PropertyValues,
|
||||||
|
query,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
import "../ha-icon-button";
|
||||||
|
import "./state-badge";
|
||||||
|
|
||||||
|
export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean;
|
||||||
|
|
||||||
|
const rowRenderer = (root: HTMLElement, _owner, model: { item: string }) => {
|
||||||
|
if (!root.firstElementChild) {
|
||||||
|
root.innerHTML = `
|
||||||
|
<style>
|
||||||
|
paper-item {
|
||||||
|
margin: -10px;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<paper-item></paper-item>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
root.querySelector("paper-item")!.textContent = model.item;
|
||||||
|
};
|
||||||
|
|
||||||
|
@customElement("ha-entity-attribute-picker")
|
||||||
|
class HaEntityAttributePicker extends LitElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public entityId?: string;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public autofocus = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean, attribute: "allow-custom-value" })
|
||||||
|
public allowCustomValue;
|
||||||
|
|
||||||
|
@property() public label?: string;
|
||||||
|
|
||||||
|
@property() public value?: string;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) private _opened = false;
|
||||||
|
|
||||||
|
@query("vaadin-combo-box-light") private _comboBox!: HTMLElement;
|
||||||
|
|
||||||
|
protected shouldUpdate(changedProps: PropertyValues) {
|
||||||
|
return !(!changedProps.has("_opened") && this._opened);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps: PropertyValues) {
|
||||||
|
if (changedProps.has("_opened") && this._opened) {
|
||||||
|
const state = this.entityId ? this.hass.states[this.entityId] : undefined;
|
||||||
|
(this._comboBox as any).items = state
|
||||||
|
? Object.keys(state.attributes)
|
||||||
|
: [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
if (!this.hass) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<vaadin-combo-box-light
|
||||||
|
.value=${this._value}
|
||||||
|
.allowCustomValue=${this.allowCustomValue}
|
||||||
|
.renderer=${rowRenderer}
|
||||||
|
@opened-changed=${this._openedChanged}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
>
|
||||||
|
<paper-input
|
||||||
|
.autofocus=${this.autofocus}
|
||||||
|
.label=${this.label ??
|
||||||
|
this.hass.localize(
|
||||||
|
"ui.components.entity.entity-attribute-picker.attribute"
|
||||||
|
)}
|
||||||
|
.value=${this._value}
|
||||||
|
.disabled=${this.disabled || !this.entityId}
|
||||||
|
class="input"
|
||||||
|
autocapitalize="none"
|
||||||
|
autocomplete="off"
|
||||||
|
autocorrect="off"
|
||||||
|
spellcheck="false"
|
||||||
|
>
|
||||||
|
${this.value
|
||||||
|
? html`
|
||||||
|
<ha-icon-button
|
||||||
|
aria-label=${this.hass.localize(
|
||||||
|
"ui.components.entity.entity-picker.clear"
|
||||||
|
)}
|
||||||
|
slot="suffix"
|
||||||
|
class="clear-button"
|
||||||
|
icon="hass:close"
|
||||||
|
@click=${this._clearValue}
|
||||||
|
no-ripple
|
||||||
|
>
|
||||||
|
Clear
|
||||||
|
</ha-icon-button>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
|
||||||
|
<ha-icon-button
|
||||||
|
aria-label=${this.hass.localize(
|
||||||
|
"ui.components.entity.entity-attribute-picker.show_attributes"
|
||||||
|
)}
|
||||||
|
slot="suffix"
|
||||||
|
class="toggle-button"
|
||||||
|
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
|
||||||
|
>
|
||||||
|
Toggle
|
||||||
|
</ha-icon-button>
|
||||||
|
</paper-input>
|
||||||
|
</vaadin-combo-box-light>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _clearValue(ev: Event) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this._setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private get _value() {
|
||||||
|
return this.value || "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private _openedChanged(ev: PolymerChangedEvent<boolean>) {
|
||||||
|
this._opened = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: PolymerChangedEvent<string>) {
|
||||||
|
const newValue = ev.detail.value;
|
||||||
|
if (newValue !== this._value) {
|
||||||
|
this._setValue(newValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _setValue(value: string) {
|
||||||
|
this.value = value;
|
||||||
|
setTimeout(() => {
|
||||||
|
fireEvent(this, "value-changed", { value });
|
||||||
|
fireEvent(this, "change");
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
paper-input > ha-icon-button {
|
||||||
|
--mdc-icon-button-size: 24px;
|
||||||
|
padding: 0px 2px;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-entity-attribute-picker": HaEntityAttributePicker;
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,3 @@
|
|||||||
import "../ha-icon-button";
|
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import "@polymer/paper-item/paper-icon-item";
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
import "@polymer/paper-item/paper-item-body";
|
import "@polymer/paper-item/paper-item-body";
|
||||||
@ -20,6 +19,7 @@ import { computeDomain } from "../../common/entity/compute_domain";
|
|||||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
|
import "../ha-icon-button";
|
||||||
import "./state-badge";
|
import "./state-badge";
|
||||||
|
|
||||||
export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean;
|
export type HaEntityPickerEntityFilterFunc = (entityId: HassEntity) => boolean;
|
||||||
@ -95,6 +95,8 @@ class HaEntityPicker extends LitElement {
|
|||||||
|
|
||||||
@query("vaadin-combo-box-light") private _comboBox!: HTMLElement;
|
@query("vaadin-combo-box-light") private _comboBox!: HTMLElement;
|
||||||
|
|
||||||
|
private _initedStates = false;
|
||||||
|
|
||||||
private _getStates = memoizeOne(
|
private _getStates = memoizeOne(
|
||||||
(
|
(
|
||||||
_opened: boolean,
|
_opened: boolean,
|
||||||
@ -148,11 +150,18 @@ class HaEntityPicker extends LitElement {
|
|||||||
);
|
);
|
||||||
|
|
||||||
protected shouldUpdate(changedProps: PropertyValues) {
|
protected shouldUpdate(changedProps: PropertyValues) {
|
||||||
|
if (
|
||||||
|
changedProps.has("value") ||
|
||||||
|
changedProps.has("label") ||
|
||||||
|
changedProps.has("disabled")
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return !(!changedProps.has("_opened") && this._opened);
|
return !(!changedProps.has("_opened") && this._opened);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
if (changedProps.has("_opened") && this._opened) {
|
if (!this._initedStates || (changedProps.has("_opened") && this._opened)) {
|
||||||
const states = this._getStates(
|
const states = this._getStates(
|
||||||
this._opened,
|
this._opened,
|
||||||
this.hass,
|
this.hass,
|
||||||
@ -162,6 +171,7 @@ class HaEntityPicker extends LitElement {
|
|||||||
this.includeDeviceClasses
|
this.includeDeviceClasses
|
||||||
);
|
);
|
||||||
(this._comboBox as any).items = states;
|
(this._comboBox as any).items = states;
|
||||||
|
this._initedStates = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +179,6 @@ class HaEntityPicker extends LitElement {
|
|||||||
if (!this.hass) {
|
if (!this.hass) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<vaadin-combo-box-light
|
<vaadin-combo-box-light
|
||||||
item-value-path="entity_id"
|
item-value-path="entity_id"
|
||||||
|
@ -64,6 +64,7 @@ export class HaDialog extends MwcDialog {
|
|||||||
}
|
}
|
||||||
.mdc-dialog .mdc-dialog__surface {
|
.mdc-dialog .mdc-dialog__surface {
|
||||||
position: var(--dialog-surface-position, relative);
|
position: var(--dialog-surface-position, relative);
|
||||||
|
top: var(--dialog-surface-top);
|
||||||
min-height: var(--mdc-dialog-min-height, auto);
|
min-height: var(--mdc-dialog-min-height, auto);
|
||||||
}
|
}
|
||||||
:host([flexContent]) .mdc-dialog .mdc-dialog__content {
|
:host([flexContent]) .mdc-dialog .mdc-dialog__content {
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
import { html } from "lit-element";
|
|
||||||
|
|
||||||
export const sortStyles = html`
|
|
||||||
<style>
|
|
||||||
#sortable a:nth-of-type(2n) paper-icon-item {
|
|
||||||
animation-name: keyframes1;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
transform-origin: 50% 10%;
|
|
||||||
animation-delay: -0.75s;
|
|
||||||
animation-duration: 0.25s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sortable a:nth-of-type(2n-1) paper-icon-item {
|
|
||||||
animation-name: keyframes2;
|
|
||||||
animation-iteration-count: infinite;
|
|
||||||
animation-direction: alternate;
|
|
||||||
transform-origin: 30% 5%;
|
|
||||||
animation-delay: -0.5s;
|
|
||||||
animation-duration: 0.33s;
|
|
||||||
}
|
|
||||||
|
|
||||||
#sortable {
|
|
||||||
outline: none;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sortable-ghost {
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sortable-fallback {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes keyframes1 {
|
|
||||||
0% {
|
|
||||||
transform: rotate(-1deg);
|
|
||||||
animation-timing-function: ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: rotate(1.5deg);
|
|
||||||
animation-timing-function: ease-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes keyframes2 {
|
|
||||||
0% {
|
|
||||||
transform: rotate(1deg);
|
|
||||||
animation-timing-function: ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: rotate(-1.5deg);
|
|
||||||
animation-timing-function: ease-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hide-panel {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([expanded]) .hide-panel {
|
|
||||||
display: inline-flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-icon-item.hidden-panel,
|
|
||||||
paper-icon-item.hidden-panel span,
|
|
||||||
paper-icon-item.hidden-panel ha-icon[slot="item-icon"] {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
`;
|
|
@ -23,7 +23,6 @@ import {
|
|||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import { guard } from "lit-html/directives/guard";
|
import { guard } from "lit-html/directives/guard";
|
||||||
@ -31,6 +30,7 @@ import memoizeOne from "memoize-one";
|
|||||||
import { LocalStorage } from "../common/decorators/local-storage";
|
import { LocalStorage } from "../common/decorators/local-storage";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { computeDomain } from "../common/entity/compute_domain";
|
import { computeDomain } from "../common/entity/compute_domain";
|
||||||
|
import { navigate } from "../common/navigate";
|
||||||
import { compare } from "../common/string/compare";
|
import { compare } from "../common/string/compare";
|
||||||
import { computeRTL } from "../common/util/compute_rtl";
|
import { computeRTL } from "../common/util/compute_rtl";
|
||||||
import { ActionHandlerDetail } from "../data/lovelace";
|
import { ActionHandlerDetail } from "../data/lovelace";
|
||||||
@ -160,7 +160,7 @@ const computePanels = memoizeOne(
|
|||||||
|
|
||||||
let Sortable;
|
let Sortable;
|
||||||
|
|
||||||
let sortStyles: TemplateResult;
|
let sortStyles: CSSResult;
|
||||||
|
|
||||||
@customElement("ha-sidebar")
|
@customElement("ha-sidebar")
|
||||||
class HaSidebar extends LitElement {
|
class HaSidebar extends LitElement {
|
||||||
@ -228,7 +228,13 @@ class HaSidebar extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${this._editMode ? sortStyles : ""}
|
${this._editMode
|
||||||
|
? html`
|
||||||
|
<style>
|
||||||
|
${sortStyles?.cssText}
|
||||||
|
</style>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
${!this.narrow
|
${!this.narrow
|
||||||
? html`
|
? html`
|
||||||
@ -480,10 +486,10 @@ class HaSidebar extends LitElement {
|
|||||||
if (!Sortable) {
|
if (!Sortable) {
|
||||||
const [sortableImport, sortStylesImport] = await Promise.all([
|
const [sortableImport, sortStylesImport] = await Promise.all([
|
||||||
import("sortablejs/modular/sortable.core.esm"),
|
import("sortablejs/modular/sortable.core.esm"),
|
||||||
import("./ha-sidebar-sort-styles"),
|
import("../resources/ha-sortable-style"),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
sortStyles = sortStylesImport.sortStyles;
|
sortStyles = sortStylesImport.sortableStyles;
|
||||||
|
|
||||||
Sortable = sortableImport.Sortable;
|
Sortable = sortableImport.Sortable;
|
||||||
Sortable.mount(sortableImport.OnSpill);
|
Sortable.mount(sortableImport.OnSpill);
|
||||||
@ -649,6 +655,10 @@ class HaSidebar extends LitElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handlePanelTap(ev: Event) {
|
||||||
|
navigate(this, (ev.currentTarget as HTMLAnchorElement).href);
|
||||||
|
}
|
||||||
|
|
||||||
private _renderPanel(
|
private _renderPanel(
|
||||||
urlPath: string,
|
urlPath: string,
|
||||||
title: string | null,
|
title: string | null,
|
||||||
@ -661,6 +671,7 @@ class HaSidebar extends LitElement {
|
|||||||
href="${`/${urlPath}`}"
|
href="${`/${urlPath}`}"
|
||||||
data-panel="${urlPath}"
|
data-panel="${urlPath}"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
|
@tap=${this._handlePanelTap}
|
||||||
@mouseenter=${this._itemMouseEnter}
|
@mouseenter=${this._itemMouseEnter}
|
||||||
@mouseleave=${this._itemMouseLeave}
|
@mouseleave=${this._itemMouseLeave}
|
||||||
>
|
>
|
||||||
|
@ -93,6 +93,9 @@ class DialogMediaPlayerBrowse extends LitElement {
|
|||||||
@media (min-width: 800px) {
|
@media (min-width: 800px) {
|
||||||
ha-dialog {
|
ha-dialog {
|
||||||
--mdc-dialog-max-width: 800px;
|
--mdc-dialog-max-width: 800px;
|
||||||
|
--dialog-surface-position: fixed;
|
||||||
|
--dialog-surface-top: 40px;
|
||||||
|
--mdc-dialog-max-height: calc(100% - 72px);
|
||||||
}
|
}
|
||||||
ha-media-player-browse {
|
ha-media-player-browse {
|
||||||
width: 700px;
|
width: 700px;
|
||||||
|
@ -18,8 +18,10 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import { ifDefined } from "lit-html/directives/if-defined";
|
import { ifDefined } from "lit-html/directives/if-defined";
|
||||||
|
import { styleMap } from "lit-html/directives/style-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
import { compare } from "../../common/string/compare";
|
||||||
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
import { computeRTLDirection } from "../../common/util/compute_rtl";
|
||||||
import { debounce } from "../../common/util/debounce";
|
import { debounce } from "../../common/util/debounce";
|
||||||
import {
|
import {
|
||||||
@ -30,6 +32,7 @@ import {
|
|||||||
MediaPlayerBrowseAction,
|
MediaPlayerBrowseAction,
|
||||||
} from "../../data/media-player";
|
} from "../../data/media-player";
|
||||||
import type { MediaPlayerItem } from "../../data/media-player";
|
import type { MediaPlayerItem } from "../../data/media-player";
|
||||||
|
import { showAlertDialog } from "../../dialogs/generic/show-dialog-box";
|
||||||
import { installResizeObserver } from "../../panels/lovelace/common/install-resize-observer";
|
import { installResizeObserver } from "../../panels/lovelace/common/install-resize-observer";
|
||||||
import { haStyle } from "../../resources/styles";
|
import { haStyle } from "../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
@ -65,6 +68,8 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
|
|
||||||
@internalProperty() private _loading = false;
|
@internalProperty() private _loading = false;
|
||||||
|
|
||||||
|
@internalProperty() private _error?: { message: string; code: string };
|
||||||
|
|
||||||
@internalProperty() private _mediaPlayerItems: MediaPlayerItem[] = [];
|
@internalProperty() private _mediaPlayerItems: MediaPlayerItem[] = [];
|
||||||
|
|
||||||
private _resizeObserver?: ResizeObserver;
|
private _resizeObserver?: ResizeObserver;
|
||||||
@ -89,11 +94,55 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
this._navigate(item);
|
this._navigate(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _renderError(err: { message: string; code: string }) {
|
||||||
|
if (err.message === "Media directory does not exist.") {
|
||||||
|
return html`
|
||||||
|
<h2>No local media found.</h2>
|
||||||
|
<p>
|
||||||
|
It looks like you have not yet created a media directory.
|
||||||
|
<br />Create a directory with the name <b>"media"</b> in the
|
||||||
|
configuration directory of Home Assistant
|
||||||
|
(${this.hass.config.config_dir}). <br />Place your video, audio and
|
||||||
|
image files in this directory to be able to browse and play them in
|
||||||
|
the browser or on supported media players.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Check the
|
||||||
|
<a
|
||||||
|
href="https://www.home-assistant.io/integrations/media_source/#local-media"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer"
|
||||||
|
>documentation</a
|
||||||
|
>
|
||||||
|
for more info
|
||||||
|
</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
return err.message;
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (this._loading) {
|
if (this._loading) {
|
||||||
return html`<ha-circular-progress active></ha-circular-progress>`;
|
return html`<ha-circular-progress active></ha-circular-progress>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._error && !this._mediaPlayerItems.length) {
|
||||||
|
if (this.dialog) {
|
||||||
|
this._closeDialogAction();
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.components.media-browser.media_browsing_error"
|
||||||
|
),
|
||||||
|
text: this._renderError(this._error),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return html`<div class="container error">
|
||||||
|
${this._renderError(this._error)}
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!this._mediaPlayerItems.length) {
|
if (!this._mediaPlayerItems.length) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
@ -130,7 +179,11 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
? html`
|
? html`
|
||||||
<div
|
<div
|
||||||
class="img"
|
class="img"
|
||||||
style="background-image: url(${currentItem.thumbnail})"
|
style=${styleMap({
|
||||||
|
backgroundImage: currentItem.thumbnail
|
||||||
|
? `url(${currentItem.thumbnail})`
|
||||||
|
: "none",
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
${this._narrow && currentItem?.can_play
|
${this._narrow && currentItem?.can_play
|
||||||
? html`
|
? html`
|
||||||
@ -209,7 +262,11 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
${currentItem.children?.length
|
${this._error
|
||||||
|
? html`<div class="container error">
|
||||||
|
${this._renderError(this._error)}
|
||||||
|
</div>`
|
||||||
|
: currentItem.children?.length
|
||||||
? hasExpandableChildren
|
? hasExpandableChildren
|
||||||
? html`
|
? html`
|
||||||
<div class="children">
|
<div class="children">
|
||||||
@ -218,12 +275,16 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
<div
|
<div
|
||||||
class="child"
|
class="child"
|
||||||
.item=${child}
|
.item=${child}
|
||||||
@click=${this._navigateForward}
|
@click=${this._childClicked}
|
||||||
>
|
>
|
||||||
<div class="ha-card-parent">
|
<div class="ha-card-parent">
|
||||||
<ha-card
|
<ha-card
|
||||||
outlined
|
outlined
|
||||||
style="background-image: url(${child.thumbnail})"
|
style=${styleMap({
|
||||||
|
backgroundImage: child.thumbnail
|
||||||
|
? `url(${child.thumbnail})`
|
||||||
|
: "none",
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
${child.can_expand && !child.thumbnail
|
${child.can_expand && !child.thumbnail
|
||||||
? html`
|
? html`
|
||||||
@ -305,7 +366,9 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</mwc-list>
|
</mwc-list>
|
||||||
`
|
`
|
||||||
: this.hass.localize("ui.components.media-browser.no_items")}
|
: html`<div class="container">
|
||||||
|
${this.hass.localize("ui.components.media-browser.no_items")}
|
||||||
|
</div>`}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,11 +394,22 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._fetchData(this.mediaContentId, this.mediaContentType).then(
|
if (changedProps.has("entityId")) {
|
||||||
(itemData) => {
|
this._error = undefined;
|
||||||
this._mediaPlayerItems = [itemData];
|
this._mediaPlayerItems = [];
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
this._fetchData(this.mediaContentId, this.mediaContentType)
|
||||||
|
.then((itemData) => {
|
||||||
|
if (!itemData) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._mediaPlayerItems = [itemData];
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
this._error = err;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private _actionClicked(ev: MouseEvent): void {
|
private _actionClicked(ev: MouseEvent): void {
|
||||||
@ -349,21 +423,41 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
fireEvent(this, "media-picked", { item });
|
fireEvent(this, "media-picked", { item });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _navigateForward(ev: MouseEvent): Promise<void> {
|
private async _childClicked(ev: MouseEvent): Promise<void> {
|
||||||
const target = ev.currentTarget as any;
|
const target = ev.currentTarget as any;
|
||||||
const item: MediaPlayerItem = target.item;
|
const item: MediaPlayerItem = target.item;
|
||||||
|
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!item.can_expand) {
|
||||||
|
this._runAction(item);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this._navigate(item);
|
this._navigate(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _navigate(item: MediaPlayerItem) {
|
private async _navigate(item: MediaPlayerItem) {
|
||||||
const itemData = await this._fetchData(
|
this._error = undefined;
|
||||||
|
|
||||||
|
let itemData: MediaPlayerItem;
|
||||||
|
|
||||||
|
try {
|
||||||
|
itemData = await this._fetchData(
|
||||||
item.media_content_id,
|
item.media_content_id,
|
||||||
item.media_content_type
|
item.media_content_type
|
||||||
);
|
);
|
||||||
|
} catch (err) {
|
||||||
|
showAlertDialog(this, {
|
||||||
|
title: this.hass.localize(
|
||||||
|
"ui.components.media-browser.media_browsing_error"
|
||||||
|
),
|
||||||
|
text: this._renderError(err),
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.scrollTo(0, 0);
|
this.scrollTo(0, 0);
|
||||||
this._mediaPlayerItems = [...this._mediaPlayerItems, itemData];
|
this._mediaPlayerItems = [...this._mediaPlayerItems, itemData];
|
||||||
@ -382,6 +476,13 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
mediaContentType
|
mediaContentType
|
||||||
)
|
)
|
||||||
: await browseLocalMediaPlayer(this.hass, mediaContentId);
|
: await browseLocalMediaPlayer(this.hass, mediaContentId);
|
||||||
|
itemData.children = itemData.children?.sort((first, second) =>
|
||||||
|
!first.can_expand && second.can_expand
|
||||||
|
? 1
|
||||||
|
: first.can_expand && !second.can_expand
|
||||||
|
? -1
|
||||||
|
: compare(first.title, second.title)
|
||||||
|
);
|
||||||
|
|
||||||
return itemData;
|
return itemData;
|
||||||
}
|
}
|
||||||
@ -409,8 +510,8 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
this._resizeObserver.observe(this);
|
this._resizeObserver.observe(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _hasExpandableChildren = memoizeOne((children) =>
|
private _hasExpandableChildren = memoizeOne((children?: MediaPlayerItem[]) =>
|
||||||
children.find((item: MediaPlayerItem) => item.can_expand)
|
children?.find((item: MediaPlayerItem) => item.can_expand)
|
||||||
);
|
);
|
||||||
|
|
||||||
private _closeDialogAction(): void {
|
private _closeDialogAction(): void {
|
||||||
@ -429,18 +530,16 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 1px solid var(--divider-color);
|
border-bottom: 1px solid var(--divider-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.header_button {
|
|
||||||
position: relative;
|
|
||||||
top: 14px;
|
|
||||||
right: -8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
background-color: var(--card-background-color);
|
background-color: var(--card-background-color);
|
||||||
position: sticky;
|
position: sticky;
|
||||||
@ -539,9 +638,6 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
);
|
);
|
||||||
grid-gap: 16px;
|
grid-gap: 16px;
|
||||||
margin: 8px 0px;
|
margin: 8px 0px;
|
||||||
}
|
|
||||||
|
|
||||||
:host(:not([narrow])) .children {
|
|
||||||
padding: 0px 24px;
|
padding: 0px 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -683,8 +779,7 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
padding: 20px 24px 10px;
|
padding: 20px 24px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([narrow]) .media-source,
|
:host([narrow]) .media-source {
|
||||||
:host([narrow]) .children {
|
|
||||||
padding: 0 24px;
|
padding: 0 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,8 +798,8 @@ export class HaMediaPlayerBrowse extends LitElement {
|
|||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(:not([narrow])[scroll]) .header-info {
|
:host(:not([narrow])[scroll]) .header:not(.no-img) mwc-icon-button {
|
||||||
height: 75px;
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host([scroll]) .header-info mwc-button,
|
:host([scroll]) .header-info mwc-button,
|
||||||
|
@ -3,7 +3,7 @@ import {
|
|||||||
HassEntityBase,
|
HassEntityBase,
|
||||||
} from "home-assistant-js-websocket";
|
} from "home-assistant-js-websocket";
|
||||||
import { navigate } from "../common/navigate";
|
import { navigate } from "../common/navigate";
|
||||||
import { HomeAssistant, Context } from "../types";
|
import { Context, HomeAssistant } from "../types";
|
||||||
import { DeviceCondition, DeviceTrigger } from "./device_automation";
|
import { DeviceCondition, DeviceTrigger } from "./device_automation";
|
||||||
import { Action } from "./script";
|
import { Action } from "./script";
|
||||||
|
|
||||||
@ -15,6 +15,7 @@ export interface AutomationEntity extends HassEntityBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface AutomationConfig {
|
export interface AutomationConfig {
|
||||||
|
id?: string;
|
||||||
alias: string;
|
alias: string;
|
||||||
description: string;
|
description: string;
|
||||||
trigger: Trigger[];
|
trigger: Trigger[];
|
||||||
@ -32,7 +33,8 @@ export interface ForDict {
|
|||||||
|
|
||||||
export interface StateTrigger {
|
export interface StateTrigger {
|
||||||
platform: "state";
|
platform: "state";
|
||||||
entity_id?: string;
|
entity_id: string;
|
||||||
|
attribute?: string;
|
||||||
from?: string | number;
|
from?: string | number;
|
||||||
to?: string | number;
|
to?: string | number;
|
||||||
for?: string | number | ForDict;
|
for?: string | number | ForDict;
|
||||||
@ -59,6 +61,7 @@ export interface HassTrigger {
|
|||||||
export interface NumericStateTrigger {
|
export interface NumericStateTrigger {
|
||||||
platform: "numeric_state";
|
platform: "numeric_state";
|
||||||
entity_id: string;
|
entity_id: string;
|
||||||
|
attribute?: string;
|
||||||
above?: number;
|
above?: number;
|
||||||
below?: number;
|
below?: number;
|
||||||
value_template?: string;
|
value_template?: string;
|
||||||
@ -136,12 +139,14 @@ export interface LogicalCondition {
|
|||||||
export interface StateCondition {
|
export interface StateCondition {
|
||||||
condition: "state";
|
condition: "state";
|
||||||
entity_id: string;
|
entity_id: string;
|
||||||
|
attribute?: string;
|
||||||
state: string | number;
|
state: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface NumericStateCondition {
|
export interface NumericStateCondition {
|
||||||
condition: "numeric_state";
|
condition: "numeric_state";
|
||||||
entity_id: string;
|
entity_id: string;
|
||||||
|
attribute?: string;
|
||||||
above?: number;
|
above?: number;
|
||||||
below?: number;
|
below?: number;
|
||||||
value_template?: string;
|
value_template?: string;
|
||||||
|
@ -13,6 +13,8 @@ export const DISCOVERY_SOURCES = [
|
|||||||
"discovery",
|
"discovery",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const ATTENTION_SOURCES = ["reauth"];
|
||||||
|
|
||||||
export const createConfigFlow = (hass: HomeAssistant, handler: string) =>
|
export const createConfigFlow = (hass: HomeAssistant, handler: string) =>
|
||||||
hass.callApi<DataEntryFlowStep>("POST", "config/config_entries/flow", {
|
hass.callApi<DataEntryFlowStep>("POST", "config/config_entries/flow", {
|
||||||
handler,
|
handler,
|
||||||
|
@ -9,7 +9,7 @@ export const hassioApiResultExtractor = <T>(response: HassioResponse<T>) =>
|
|||||||
export const extractApiErrorMessage = (error: any): string => {
|
export const extractApiErrorMessage = (error: any): string => {
|
||||||
return typeof error === "object"
|
return typeof error === "object"
|
||||||
? typeof error.body === "object"
|
? typeof error.body === "object"
|
||||||
? error.body.message || "Unkown error, see logs"
|
? error.body.message || "Unknown error, see logs"
|
||||||
: error.body || "Unkown error, see logs"
|
: error.body || "Unknown error, see logs"
|
||||||
: error;
|
: error;
|
||||||
};
|
};
|
||||||
|
@ -5,7 +5,7 @@ import {
|
|||||||
import { computeObjectId } from "../common/entity/compute_object_id";
|
import { computeObjectId } from "../common/entity/compute_object_id";
|
||||||
import { navigate } from "../common/navigate";
|
import { navigate } from "../common/navigate";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
import { Condition } from "./automation";
|
import { Condition, Trigger } from "./automation";
|
||||||
|
|
||||||
export const MODES = ["single", "restart", "queued", "parallel"];
|
export const MODES = ["single", "restart", "queued", "parallel"];
|
||||||
export const MODES_MAX = ["queued", "parallel"];
|
export const MODES_MAX = ["queued", "parallel"];
|
||||||
@ -56,6 +56,13 @@ export interface SceneAction {
|
|||||||
export interface WaitAction {
|
export interface WaitAction {
|
||||||
wait_template: string;
|
wait_template: string;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
continue_on_timeout?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WaitForTriggerAction {
|
||||||
|
wait_for_trigger: Trigger[];
|
||||||
|
timeout?: number;
|
||||||
|
continue_on_timeout?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RepeatAction {
|
export interface RepeatAction {
|
||||||
@ -91,6 +98,7 @@ export type Action =
|
|||||||
| DelayAction
|
| DelayAction
|
||||||
| SceneAction
|
| SceneAction
|
||||||
| WaitAction
|
| WaitAction
|
||||||
|
| WaitForTriggerAction
|
||||||
| RepeatAction
|
| RepeatAction
|
||||||
| ChooseAction;
|
| ChooseAction;
|
||||||
|
|
||||||
|
@ -5,19 +5,19 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
import "../../components/ha-dialog";
|
import "../../components/ha-dialog";
|
||||||
import "../../components/ha-switch";
|
import "../../components/ha-switch";
|
||||||
import { PolymerChangedEvent } from "../../polymer-types";
|
import { PolymerChangedEvent } from "../../polymer-types";
|
||||||
import { haStyleDialog } from "../../resources/styles";
|
import { haStyleDialog } from "../../resources/styles";
|
||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { DialogParams } from "./show-dialog-box";
|
import { DialogParams } from "./show-dialog-box";
|
||||||
import { fireEvent } from "../../common/dom/fire_event";
|
|
||||||
|
|
||||||
@customElement("dialog-box")
|
@customElement("dialog-box")
|
||||||
class DialogBox extends LitElement {
|
class DialogBox extends LitElement {
|
||||||
@ -114,8 +114,8 @@ class DialogBox extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _dismiss(): void {
|
private _dismiss(): void {
|
||||||
if (this._params!.cancel) {
|
if (this._params?.cancel) {
|
||||||
this._params!.cancel();
|
this._params.cancel();
|
||||||
}
|
}
|
||||||
this._close();
|
this._close();
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${stateObj.state !== "off" &&
|
${![UNAVAILABLE, UNKNOWN, "off"].includes(stateObj.state) &&
|
||||||
supportsFeature(stateObj, SUPPORT_SELECT_SOURCE) &&
|
supportsFeature(stateObj, SUPPORT_SELECT_SOURCE) &&
|
||||||
stateObj.attributes.source_list?.length
|
stateObj.attributes.source_list?.length
|
||||||
? html`
|
? html`
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
}
|
}
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html {
|
html {
|
||||||
background-color: var(--primary-background-color, #111111);
|
background-color: #111111;
|
||||||
}
|
}
|
||||||
#ha-init-skeleton::before {
|
#ha-init-skeleton::before {
|
||||||
background-color: #1c1c1c;
|
background-color: #1c1c1c;
|
||||||
|
@ -5,6 +5,15 @@
|
|||||||
<link rel="preload" href="<%= latestPageJS %>" as="script" crossorigin="use-credentials" />
|
<link rel="preload" href="<%= latestPageJS %>" as="script" crossorigin="use-credentials" />
|
||||||
<%= renderTemplate('_header') %>
|
<%= renderTemplate('_header') %>
|
||||||
<style>
|
<style>
|
||||||
|
html {
|
||||||
|
color: var(--primary-text-color, #212121);
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
background-color: #111111;
|
||||||
|
color: var(--primary-text-color, #e1e1e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
.content {
|
.content {
|
||||||
padding: 20px 16px;
|
padding: 20px 16px;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
@ -23,14 +32,6 @@
|
|||||||
.header img {
|
.header img {
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
}
|
}
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
body {
|
|
||||||
background-color: #111111;
|
|
||||||
color: #e1e1e1;
|
|
||||||
--primary-text-color: #e1e1e1;
|
|
||||||
--secondary-text-color: #9b9b9b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -63,6 +63,7 @@ class HassErrorScreen extends LitElement {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
|
color: var(--primary-text-color);
|
||||||
height: calc(100% - 64px);
|
height: calc(100% - 64px);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
|
||||||
import "@material/mwc-list/mwc-list-item";
|
|
||||||
import "@material/mwc-icon-button";
|
import "@material/mwc-icon-button";
|
||||||
import "../../../../components/ha-button-menu";
|
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import { mdiDotsVertical, mdiArrowUp, mdiArrowDown } from "@mdi/js";
|
import { mdiArrowDown, mdiArrowUp, mdiDotsVertical } from "@mdi/js";
|
||||||
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
|
import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
|
||||||
@ -12,29 +11,31 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-button-menu";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
|
import "../../../../components/ha-svg-icon";
|
||||||
import type { Action } from "../../../../data/script";
|
import type { Action } from "../../../../data/script";
|
||||||
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||||
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
import { handleStructError } from "../../../lovelace/common/structs/handle-errors";
|
||||||
|
import "./types/ha-automation-action-choose";
|
||||||
import "./types/ha-automation-action-condition";
|
import "./types/ha-automation-action-condition";
|
||||||
import "./types/ha-automation-action-delay";
|
import "./types/ha-automation-action-delay";
|
||||||
import "./types/ha-automation-action-device_id";
|
import "./types/ha-automation-action-device_id";
|
||||||
import "./types/ha-automation-action-event";
|
import "./types/ha-automation-action-event";
|
||||||
|
import "./types/ha-automation-action-repeat";
|
||||||
import "./types/ha-automation-action-scene";
|
import "./types/ha-automation-action-scene";
|
||||||
import "./types/ha-automation-action-service";
|
import "./types/ha-automation-action-service";
|
||||||
|
import "./types/ha-automation-action-wait_for_trigger";
|
||||||
import "./types/ha-automation-action-wait_template";
|
import "./types/ha-automation-action-wait_template";
|
||||||
import "./types/ha-automation-action-repeat";
|
|
||||||
import "./types/ha-automation-action-choose";
|
|
||||||
import { handleStructError } from "../../../lovelace/common/structs/handle-errors";
|
|
||||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
|
||||||
import { haStyle } from "../../../../resources/styles";
|
|
||||||
|
|
||||||
const OPTIONS = [
|
const OPTIONS = [
|
||||||
"condition",
|
"condition",
|
||||||
@ -44,6 +45,7 @@ const OPTIONS = [
|
|||||||
"scene",
|
"scene",
|
||||||
"service",
|
"service",
|
||||||
"wait_template",
|
"wait_template",
|
||||||
|
"wait_for_trigger",
|
||||||
"repeat",
|
"repeat",
|
||||||
"choose",
|
"choose",
|
||||||
];
|
];
|
||||||
@ -166,7 +168,7 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
"ui.panel.config.automation.editor.edit_yaml"
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
)}
|
)}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
<mwc-list-item disabled>
|
<mwc-list-item>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.actions.duplicate"
|
"ui.panel.config.automation.editor.actions.duplicate"
|
||||||
)}
|
)}
|
||||||
@ -261,6 +263,7 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
this._switchYamlMode();
|
this._switchYamlMode();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
fireEvent(this, "duplicate");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this._onDelete();
|
this._onDelete();
|
||||||
|
@ -28,6 +28,7 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
.index=${idx}
|
.index=${idx}
|
||||||
.totalActions=${this.actions.length}
|
.totalActions=${this.actions.length}
|
||||||
.action=${action}
|
.action=${action}
|
||||||
|
@duplicate=${this._duplicateAction}
|
||||||
@move-action=${this._move}
|
@move-action=${this._move}
|
||||||
@value-changed=${this._actionChanged}
|
@value-changed=${this._actionChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -78,6 +79,14 @@ export default class HaAutomationAction extends LitElement {
|
|||||||
fireEvent(this, "value-changed", { value: actions });
|
fireEvent(this, "value-changed", { value: actions });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _duplicateAction(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const index = (ev.target as any).index;
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: this.actions.concat(this.actions[index]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
ha-automation-action-row,
|
ha-automation-action-row,
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
|
import { mdiDelete } from "@mdi/js";
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
import {
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
CSSResult,
|
|
||||||
css,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { html } from "lit-html";
|
import { html } from "lit-html";
|
||||||
import { Action, ChooseAction } from "../../../../../data/script";
|
|
||||||
import { HomeAssistant } from "../../../../../types";
|
|
||||||
import { ActionElement } from "../ha-automation-action-row";
|
|
||||||
import "../../condition/ha-automation-condition-editor";
|
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import "../ha-automation-action";
|
|
||||||
import { Condition } from "../../../../../data/automation";
|
import { Condition } from "../../../../../data/automation";
|
||||||
|
import { Action, ChooseAction } from "../../../../../data/script";
|
||||||
import { haStyle } from "../../../../../resources/styles";
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
import { mdiDelete } from "@mdi/js";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import "../ha-automation-action";
|
||||||
|
import { ActionElement } from "../ha-automation-action-row";
|
||||||
|
|
||||||
@customElement("ha-automation-action-choose")
|
@customElement("ha-automation-action-choose")
|
||||||
export class HaChooseAction extends LitElement implements ActionElement {
|
export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { customElement, LitElement, property, CSSResult } from "lit-element";
|
|
||||||
import { html } from "lit-html";
|
|
||||||
import {
|
|
||||||
RepeatAction,
|
|
||||||
Action,
|
|
||||||
CountRepeat,
|
|
||||||
WhileRepeat,
|
|
||||||
UntilRepeat,
|
|
||||||
} from "../../../../../data/script";
|
|
||||||
import { HomeAssistant } from "../../../../../types";
|
|
||||||
import { ActionElement } from "../ha-automation-action-row";
|
|
||||||
import "../../condition/ha-automation-condition-editor";
|
|
||||||
import type { PaperListboxElement } from "@polymer/paper-listbox";
|
import type { PaperListboxElement } from "@polymer/paper-listbox";
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
import { CSSResult, customElement, LitElement, property } from "lit-element";
|
||||||
|
import { html } from "lit-html";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import "../ha-automation-action";
|
import {
|
||||||
import { Condition } from "../../../../lovelace/common/validate-condition";
|
Action,
|
||||||
|
CountRepeat,
|
||||||
|
RepeatAction,
|
||||||
|
UntilRepeat,
|
||||||
|
WhileRepeat,
|
||||||
|
} from "../../../../../data/script";
|
||||||
import { haStyle } from "../../../../../resources/styles";
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { Condition } from "../../../../lovelace/common/validate-condition";
|
||||||
|
import "../ha-automation-action";
|
||||||
|
import { ActionElement } from "../ha-automation-action-row";
|
||||||
|
|
||||||
const OPTIONS = ["count", "while", "until"];
|
const OPTIONS = ["count", "while", "until"];
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import {
|
|||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { html } from "lit-html";
|
import { html } from "lit-html";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { any, assert, object, optional, string } from "superstruct";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import { computeDomain } from "../../../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../../../common/entity/compute_domain";
|
||||||
import { computeObjectId } from "../../../../../common/entity/compute_object_id";
|
import { computeObjectId } from "../../../../../common/entity/compute_object_id";
|
||||||
@ -18,14 +19,13 @@ import type { HaYamlEditor } from "../../../../../components/ha-yaml-editor";
|
|||||||
import { ServiceAction } from "../../../../../data/script";
|
import { ServiceAction } from "../../../../../data/script";
|
||||||
import type { PolymerChangedEvent } from "../../../../../polymer-types";
|
import type { PolymerChangedEvent } from "../../../../../polymer-types";
|
||||||
import type { HomeAssistant } from "../../../../../types";
|
import type { HomeAssistant } from "../../../../../types";
|
||||||
import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
|
|
||||||
import { assert, optional, object, string } from "superstruct";
|
|
||||||
import { EntityId } from "../../../../lovelace/common/structs/is-entity-id";
|
import { EntityId } from "../../../../lovelace/common/structs/is-entity-id";
|
||||||
|
import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
|
||||||
|
|
||||||
const actionStruct = object({
|
const actionStruct = object({
|
||||||
service: optional(string()),
|
service: optional(string()),
|
||||||
entity_id: optional(EntityId),
|
entity_id: optional(EntityId),
|
||||||
data: optional(object()),
|
data: optional(any()),
|
||||||
});
|
});
|
||||||
|
|
||||||
@customElement("ha-automation-action-service")
|
@customElement("ha-automation-action-service")
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import "@polymer/paper-input/paper-textarea";
|
||||||
|
import { customElement, LitElement, property } from "lit-element";
|
||||||
|
import { html } from "lit-html";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../../../../../components/ha-formfield";
|
||||||
|
import { WaitForTriggerAction } from "../../../../../data/script";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import "../../trigger/ha-automation-trigger";
|
||||||
|
import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
|
||||||
|
|
||||||
|
@customElement("ha-automation-action-wait_for_trigger")
|
||||||
|
export class HaWaitForTriggerAction extends LitElement
|
||||||
|
implements ActionElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public action!: WaitForTriggerAction;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return { wait_for_trigger: [], timeout: "" };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const { wait_for_trigger, continue_on_timeout, timeout } = this.action;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.wait_for_trigger.timeout"
|
||||||
|
)}
|
||||||
|
.name=${"timeout"}
|
||||||
|
.value=${timeout}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></paper-input>
|
||||||
|
<br />
|
||||||
|
<ha-formfield
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.wait_for_trigger.timeout"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-switch
|
||||||
|
.checked=${continue_on_timeout}
|
||||||
|
@change=${this._continueChanged}
|
||||||
|
></ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
|
<ha-automation-trigger
|
||||||
|
.triggers=${wait_for_trigger}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.name=${"wait_for_trigger"}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
></ha-automation-trigger>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _continueChanged(ev) {
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.action, continue_on_timeout: ev.target.checked },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
|
handleChangeEvent(this, ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-action-wait_for_trigger": HaWaitForTriggerAction;
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ import "@polymer/paper-input/paper-input";
|
|||||||
import "@polymer/paper-input/paper-textarea";
|
import "@polymer/paper-input/paper-textarea";
|
||||||
import { customElement, LitElement, property } from "lit-element";
|
import { customElement, LitElement, property } from "lit-element";
|
||||||
import { html } from "lit-html";
|
import { html } from "lit-html";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import { WaitAction } from "../../../../../data/script";
|
import { WaitAction } from "../../../../../data/script";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
|
import { ActionElement, handleChangeEvent } from "../ha-automation-action-row";
|
||||||
@ -13,11 +14,11 @@ export class HaWaitAction extends LitElement implements ActionElement {
|
|||||||
@property() public action!: WaitAction;
|
@property() public action!: WaitAction;
|
||||||
|
|
||||||
public static get defaultConfig() {
|
public static get defaultConfig() {
|
||||||
return { wait_template: "", timeout: "" };
|
return { wait_template: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const { wait_template, timeout } = this.action;
|
const { wait_template, timeout, continue_on_timeout } = this.action;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<paper-textarea
|
<paper-textarea
|
||||||
@ -37,9 +38,24 @@ export class HaWaitAction extends LitElement implements ActionElement {
|
|||||||
.value=${timeout}
|
.value=${timeout}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></paper-input>
|
></paper-input>
|
||||||
|
<br />
|
||||||
|
<ha-formfield
|
||||||
|
.label=${this.hass.localize("ui.panel.config.automation.editor.actions.type.wait_template.continue_timeout")}
|
||||||
|
>
|
||||||
|
<ha-switch
|
||||||
|
.checked=${continue_on_timeout}
|
||||||
|
@change=${this._continueChanged}
|
||||||
|
></ha-switch>
|
||||||
|
</ha-formfield>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _continueChanged(ev) {
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.action, continue_on_timeout: ev.target.checked },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,24 @@
|
|||||||
import "../../../../components/ha-icon-button";
|
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
import "@polymer/paper-item/paper-item";
|
|
||||||
import "@material/mwc-list/mwc-list-item";
|
import "@material/mwc-list/mwc-list-item";
|
||||||
import "../../../../components/ha-button-menu";
|
|
||||||
import { mdiDotsVertical } from "@mdi/js";
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
|
import "@polymer/paper-item/paper-item";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-button-menu";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
|
import "../../../../components/ha-icon-button";
|
||||||
import { Condition } from "../../../../data/automation";
|
import { Condition } from "../../../../data/automation";
|
||||||
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import "./ha-automation-condition-editor";
|
import "./ha-automation-condition-editor";
|
||||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
|
||||||
|
|
||||||
export interface ConditionElement extends LitElement {
|
export interface ConditionElement extends LitElement {
|
||||||
condition: Condition;
|
condition: Condition;
|
||||||
@ -81,7 +81,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
|||||||
"ui.panel.config.automation.editor.edit_yaml"
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
)}
|
)}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
<mwc-list-item disabled>
|
<mwc-list-item>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.actions.duplicate"
|
"ui.panel.config.automation.editor.actions.duplicate"
|
||||||
)}
|
)}
|
||||||
@ -109,6 +109,7 @@ export default class HaAutomationConditionRow extends LitElement {
|
|||||||
this._switchYamlMode();
|
this._switchYamlMode();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
fireEvent(this, "duplicate");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this._onDelete();
|
this._onDelete();
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
html,
|
html,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
@ -20,13 +21,43 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
|
|
||||||
@property() public conditions!: Condition[];
|
@property() public conditions!: Condition[];
|
||||||
|
|
||||||
|
protected updated(changedProperties: PropertyValues) {
|
||||||
|
if (!changedProperties.has("conditions")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let updatedConditions: Condition[] | undefined;
|
||||||
|
if (!Array.isArray(this.conditions)) {
|
||||||
|
updatedConditions = [this.conditions];
|
||||||
|
}
|
||||||
|
|
||||||
|
(updatedConditions || this.conditions).forEach((condition, index) => {
|
||||||
|
if (typeof condition === "string") {
|
||||||
|
updatedConditions = updatedConditions || [...this.conditions];
|
||||||
|
updatedConditions[index] = {
|
||||||
|
condition: "template",
|
||||||
|
value_template: condition,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (updatedConditions) {
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: updatedConditions,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
|
if (!Array.isArray(this.conditions)) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
return html`
|
return html`
|
||||||
${this.conditions.map(
|
${this.conditions.map(
|
||||||
(cond, idx) => html`
|
(cond, idx) => html`
|
||||||
<ha-automation-condition-row
|
<ha-automation-condition-row
|
||||||
.index=${idx}
|
.index=${idx}
|
||||||
.condition=${cond}
|
.condition=${cond}
|
||||||
|
@duplicate=${this._duplicateCondition}
|
||||||
@value-changed=${this._conditionChanged}
|
@value-changed=${this._conditionChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
></ha-automation-condition-row>
|
></ha-automation-condition-row>
|
||||||
@ -68,6 +99,14 @@ export default class HaAutomationCondition extends LitElement {
|
|||||||
fireEvent(this, "value-changed", { value: conditions });
|
fireEvent(this, "value-changed", { value: conditions });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _duplicateCondition(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const index = (ev.target as any).index;
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: this.conditions.concat(this.conditions[index]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
ha-automation-condition-row,
|
ha-automation-condition-row,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import "@polymer/paper-input/paper-textarea";
|
import "@polymer/paper-input/paper-textarea";
|
||||||
import { customElement, html, LitElement, property } from "lit-element";
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
|
||||||
import "../../../../../components/entity/ha-entity-picker";
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
import { NumericStateCondition } from "../../../../../data/automation";
|
import { NumericStateCondition } from "../../../../../data/automation";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
@ -19,16 +18,34 @@ export default class HaNumericStateCondition extends LitElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
public render() {
|
||||||
const { value_template, entity_id, below, above } = this.condition;
|
const {
|
||||||
|
value_template,
|
||||||
|
entity_id,
|
||||||
|
attribute,
|
||||||
|
below,
|
||||||
|
above,
|
||||||
|
} = this.condition;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
.value="${entity_id}"
|
.value=${entity_id}
|
||||||
@value-changed="${this._entityPicked}"
|
.name=${"entity_id"}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
|
<ha-entity-attribute-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.entityId=${entity_id}
|
||||||
|
.value=${attribute}
|
||||||
|
.name=${"attribute"}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.state.attribute"
|
||||||
|
)}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
allow-custom-value
|
||||||
|
></ha-entity-attribute-picker>
|
||||||
<paper-input
|
<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.conditions.type.numeric_state.above"
|
"ui.panel.config.automation.editor.conditions.type.numeric_state.above"
|
||||||
@ -60,13 +77,6 @@ export default class HaNumericStateCondition extends LitElement {
|
|||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityPicked(ev) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
fireEvent(this, "value-changed", {
|
|
||||||
value: { ...this.condition, entity_id: ev.detail.value },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { customElement, html, LitElement, property } from "lit-element";
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import "../../../../../components/entity/ha-entity-attribute-picker";
|
||||||
import "../../../../../components/entity/ha-entity-picker";
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
import { StateCondition } from "../../../../../data/automation";
|
import { StateCondition } from "../../../../../data/automation";
|
||||||
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import {
|
||||||
ConditionElement,
|
ConditionElement,
|
||||||
@ -21,15 +20,27 @@ export class HaStateCondition extends LitElement implements ConditionElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const { entity_id, state } = this.condition;
|
const { entity_id, attribute, state } = this.condition;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
.value=${entity_id}
|
.value=${entity_id}
|
||||||
@value-changed=${this._entityPicked}
|
.name=${"entity_id"}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
|
<ha-entity-attribute-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.entityId=${entity_id}
|
||||||
|
.value=${attribute}
|
||||||
|
.name=${"attribute"}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.state.attribute"
|
||||||
|
)}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
allow-custom-value
|
||||||
|
></ha-entity-attribute-picker>
|
||||||
<paper-input
|
<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.conditions.type.state.state"
|
"ui.panel.config.automation.editor.conditions.type.state.state"
|
||||||
@ -44,13 +55,6 @@ export class HaStateCondition extends LitElement implements ConditionElement {
|
|||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityPicked(ev: PolymerChangedEvent<string>) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
fireEvent(this, "value-changed", {
|
|
||||||
value: { ...this.condition, entity_id: ev.detail.value },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
|
import { Radio } from "@material/mwc-radio";
|
||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { customElement, html, LitElement, property } from "lit-element";
|
import {
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
internalProperty,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
} from "lit-element";
|
||||||
|
import "../../../../../components/ha-formfield";
|
||||||
|
import "../../../../../components/ha-radio";
|
||||||
import { TimeCondition } from "../../../../../data/automation";
|
import { TimeCondition } from "../../../../../data/automation";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import {
|
||||||
@ -7,38 +16,130 @@ import {
|
|||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
} from "../ha-automation-condition-row";
|
} from "../ha-automation-condition-row";
|
||||||
|
|
||||||
|
const includeDomains = ["input_datetime"];
|
||||||
|
|
||||||
@customElement("ha-automation-condition-time")
|
@customElement("ha-automation-condition-time")
|
||||||
export class HaTimeCondition extends LitElement implements ConditionElement {
|
export class HaTimeCondition extends LitElement implements ConditionElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public condition!: TimeCondition;
|
@property() public condition!: TimeCondition;
|
||||||
|
|
||||||
|
@internalProperty() private _inputModeBefore?: boolean;
|
||||||
|
|
||||||
|
@internalProperty() private _inputModeAfter?: boolean;
|
||||||
|
|
||||||
public static get defaultConfig() {
|
public static get defaultConfig() {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const { after, before } = this.condition;
|
const { after, before } = this.condition;
|
||||||
|
|
||||||
|
const inputModeBefore =
|
||||||
|
this._inputModeBefore ?? before?.startsWith("input_datetime.");
|
||||||
|
const inputModeAfter =
|
||||||
|
this._inputModeAfter ?? after?.startsWith("input_datetime.");
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<paper-input
|
<ha-formfield
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.type_value"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-radio
|
||||||
|
@change=${this._handleModeChanged}
|
||||||
|
name="mode_after"
|
||||||
|
value="value"
|
||||||
|
?checked=${!inputModeAfter}
|
||||||
|
></ha-radio>
|
||||||
|
</ha-formfield>
|
||||||
|
<ha-formfield
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.type_input"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-radio
|
||||||
|
@change=${this._handleModeChanged}
|
||||||
|
name="mode_after"
|
||||||
|
value="input"
|
||||||
|
?checked=${inputModeAfter}
|
||||||
|
></ha-radio>
|
||||||
|
</ha-formfield>
|
||||||
|
${inputModeAfter
|
||||||
|
? html`<ha-entity-picker
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.after"
|
||||||
|
)}
|
||||||
|
.includeDomains=${includeDomains}
|
||||||
|
.name=${"after"}
|
||||||
|
.value=${after?.startsWith("input_datetime.") ? after : ""}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-entity-picker>`
|
||||||
|
: html`<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.conditions.type.time.after"
|
"ui.panel.config.automation.editor.conditions.type.time.after"
|
||||||
)}
|
)}
|
||||||
name="after"
|
name="after"
|
||||||
.value=${after}
|
.value=${after?.startsWith("input_datetime.") ? "" : after}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></paper-input>
|
></paper-input>`}
|
||||||
<paper-input
|
|
||||||
|
<ha-formfield
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.type_value"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-radio
|
||||||
|
@change=${this._handleModeChanged}
|
||||||
|
name="mode_before"
|
||||||
|
value="value"
|
||||||
|
?checked=${!inputModeBefore}
|
||||||
|
></ha-radio>
|
||||||
|
</ha-formfield>
|
||||||
|
<ha-formfield
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.type_input"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-radio
|
||||||
|
@change=${this._handleModeChanged}
|
||||||
|
name="mode_before"
|
||||||
|
value="input"
|
||||||
|
?checked=${inputModeBefore}
|
||||||
|
></ha-radio>
|
||||||
|
</ha-formfield>
|
||||||
|
${inputModeBefore
|
||||||
|
? html`<ha-entity-picker
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.conditions.type.time.before"
|
||||||
|
)}
|
||||||
|
.includeDomains=${includeDomains}
|
||||||
|
.name=${"before"}
|
||||||
|
.value=${before?.startsWith("input_datetime.") ? before : ""}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-entity-picker>`
|
||||||
|
: html`<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.conditions.type.time.before"
|
"ui.panel.config.automation.editor.conditions.type.time.before"
|
||||||
)}
|
)}
|
||||||
name="before"
|
name="before"
|
||||||
.value=${before}
|
.value=${before?.startsWith("input_datetime.") ? "" : before}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></paper-input>
|
></paper-input>`}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleModeChanged(ev: Event) {
|
||||||
|
const target = ev.target as Radio;
|
||||||
|
if (target.getAttribute("name") === "mode_after") {
|
||||||
|
this._inputModeAfter = target.value === "input";
|
||||||
|
} else {
|
||||||
|
this._inputModeBefore = target.value === "input";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
|
@ -1,28 +1,32 @@
|
|||||||
|
import "@material/mwc-fab";
|
||||||
|
import { mdiContentDuplicate, mdiContentSave, mdiDelete } from "@mdi/js";
|
||||||
import "@polymer/app-layout/app-header/app-header";
|
import "@polymer/app-layout/app-header/app-header";
|
||||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
||||||
import "@polymer/paper-input/paper-textarea";
|
import "@polymer/paper-input/paper-textarea";
|
||||||
import "../../../components/ha-icon-button";
|
import { PaperListboxElement } from "@polymer/paper-listbox";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
|
import "../../../components/ha-icon-button";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import "@material/mwc-fab";
|
|
||||||
import {
|
import {
|
||||||
AutomationConfig,
|
AutomationConfig,
|
||||||
AutomationEntity,
|
AutomationEntity,
|
||||||
Condition,
|
Condition,
|
||||||
deleteAutomation,
|
deleteAutomation,
|
||||||
getAutomationEditorInitData,
|
getAutomationEditorInitData,
|
||||||
|
showAutomationEditor,
|
||||||
Trigger,
|
Trigger,
|
||||||
triggerAutomation,
|
triggerAutomation,
|
||||||
} from "../../../data/automation";
|
} from "../../../data/automation";
|
||||||
@ -42,9 +46,6 @@ import { HaDeviceAction } from "./action/types/ha-automation-action-device_id";
|
|||||||
import "./condition/ha-automation-condition";
|
import "./condition/ha-automation-condition";
|
||||||
import "./trigger/ha-automation-trigger";
|
import "./trigger/ha-automation-trigger";
|
||||||
import { HaDeviceTrigger } from "./trigger/types/ha-automation-trigger-device";
|
import { HaDeviceTrigger } from "./trigger/types/ha-automation-trigger-device";
|
||||||
import { mdiContentSave } from "@mdi/js";
|
|
||||||
import { PaperListboxElement } from "@polymer/paper-listbox";
|
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
|
||||||
|
|
||||||
const MODES = ["single", "restart", "queued", "parallel"];
|
const MODES = ["single", "restart", "queued", "parallel"];
|
||||||
const MODES_MAX = ["queued", "parallel"];
|
const MODES_MAX = ["queued", "parallel"];
|
||||||
@ -53,6 +54,7 @@ declare global {
|
|||||||
// for fire event
|
// for fire event
|
||||||
interface HASSDomEvents {
|
interface HASSDomEvents {
|
||||||
"ui-mode-not-available": Error;
|
"ui-mode-not-available": Error;
|
||||||
|
duplicate: undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,14 +94,24 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
${!this.automationId
|
${!this.automationId
|
||||||
? ""
|
? ""
|
||||||
: html`
|
: html`
|
||||||
<ha-icon-button
|
<mwc-icon-button
|
||||||
|
slot="toolbar-icon"
|
||||||
|
title="${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.duplicate_automation"
|
||||||
|
)}"
|
||||||
|
@click=${this._duplicate}
|
||||||
|
>
|
||||||
|
<ha-svg-icon .path=${mdiContentDuplicate}></ha-svg-icon>
|
||||||
|
</mwc-icon-button>
|
||||||
|
<mwc-icon-button
|
||||||
slot="toolbar-icon"
|
slot="toolbar-icon"
|
||||||
title="${this.hass.localize(
|
title="${this.hass.localize(
|
||||||
"ui.panel.config.automation.picker.delete_automation"
|
"ui.panel.config.automation.picker.delete_automation"
|
||||||
)}"
|
)}"
|
||||||
icon="hass:delete"
|
|
||||||
@click=${this._deleteConfirm}
|
@click=${this._deleteConfirm}
|
||||||
></ha-icon-button>
|
>
|
||||||
|
<ha-svg-icon .path=${mdiDelete}></ha-svg-icon>
|
||||||
|
</mwc-icon-button>
|
||||||
`}
|
`}
|
||||||
${this._config
|
${this._config
|
||||||
? html`
|
? html`
|
||||||
@ -473,6 +485,31 @@ export class HaAutomationEditor extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _duplicate() {
|
||||||
|
if (this._dirty) {
|
||||||
|
if (
|
||||||
|
!(await showConfirmationDialog(this, {
|
||||||
|
text: this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.unsaved_confirm"
|
||||||
|
),
|
||||||
|
confirmText: this.hass!.localize("ui.common.yes"),
|
||||||
|
dismissText: this.hass!.localize("ui.common.no"),
|
||||||
|
}))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Wait for dialog to complate closing
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
|
}
|
||||||
|
showAutomationEditor(this, {
|
||||||
|
...this._config,
|
||||||
|
id: undefined,
|
||||||
|
alias: `${this._config?.alias} (${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.duplicate"
|
||||||
|
)})`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private async _deleteConfirm() {
|
private async _deleteConfirm() {
|
||||||
showConfirmationDialog(this, {
|
showConfirmationDialog(this, {
|
||||||
text: this.hass.localize(
|
text: this.hass.localize(
|
||||||
|
@ -1,25 +1,27 @@
|
|||||||
|
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
|
import "@material/mwc-list/mwc-list-item";
|
||||||
|
import { mdiDotsVertical } from "@mdi/js";
|
||||||
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
|
||||||
import "../../../../components/ha-icon-button";
|
|
||||||
import "@polymer/paper-item/paper-item";
|
import "@polymer/paper-item/paper-item";
|
||||||
import "@polymer/paper-listbox/paper-listbox";
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
import "@material/mwc-list/mwc-list-item";
|
|
||||||
import "../../../../components/ha-button-menu";
|
|
||||||
import { mdiDotsVertical } from "@mdi/js";
|
|
||||||
import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
|
import type { PaperListboxElement } from "@polymer/paper-listbox/paper-listbox";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import "../../../../components/ha-button-menu";
|
||||||
import "../../../../components/ha-card";
|
import "../../../../components/ha-card";
|
||||||
|
import "../../../../components/ha-icon-button";
|
||||||
import type { Trigger } from "../../../../data/automation";
|
import type { Trigger } from "../../../../data/automation";
|
||||||
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box";
|
||||||
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import "./types/ha-automation-trigger-device";
|
import "./types/ha-automation-trigger-device";
|
||||||
import "./types/ha-automation-trigger-event";
|
import "./types/ha-automation-trigger-event";
|
||||||
@ -29,14 +31,12 @@ import "./types/ha-automation-trigger-mqtt";
|
|||||||
import "./types/ha-automation-trigger-numeric_state";
|
import "./types/ha-automation-trigger-numeric_state";
|
||||||
import "./types/ha-automation-trigger-state";
|
import "./types/ha-automation-trigger-state";
|
||||||
import "./types/ha-automation-trigger-sun";
|
import "./types/ha-automation-trigger-sun";
|
||||||
|
import "./types/ha-automation-trigger-tag";
|
||||||
import "./types/ha-automation-trigger-template";
|
import "./types/ha-automation-trigger-template";
|
||||||
import "./types/ha-automation-trigger-time";
|
import "./types/ha-automation-trigger-time";
|
||||||
import "./types/ha-automation-trigger-time_pattern";
|
import "./types/ha-automation-trigger-time_pattern";
|
||||||
import "./types/ha-automation-trigger-webhook";
|
import "./types/ha-automation-trigger-webhook";
|
||||||
import "./types/ha-automation-trigger-zone";
|
import "./types/ha-automation-trigger-zone";
|
||||||
import "./types/ha-automation-trigger-tag";
|
|
||||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
|
||||||
import { haStyle } from "../../../../resources/styles";
|
|
||||||
|
|
||||||
const OPTIONS = [
|
const OPTIONS = [
|
||||||
"device",
|
"device",
|
||||||
@ -113,7 +113,7 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
"ui.panel.config.automation.editor.edit_yaml"
|
"ui.panel.config.automation.editor.edit_yaml"
|
||||||
)}
|
)}
|
||||||
</mwc-list-item>
|
</mwc-list-item>
|
||||||
<mwc-list-item disabled>
|
<mwc-list-item>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.actions.duplicate"
|
"ui.panel.config.automation.editor.actions.duplicate"
|
||||||
)}
|
)}
|
||||||
@ -183,6 +183,7 @@ export default class HaAutomationTriggerRow extends LitElement {
|
|||||||
this._switchYamlMode();
|
this._switchYamlMode();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
fireEvent(this, "duplicate");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
this._onDelete();
|
this._onDelete();
|
||||||
|
@ -27,6 +27,7 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
<ha-automation-trigger-row
|
<ha-automation-trigger-row
|
||||||
.index=${idx}
|
.index=${idx}
|
||||||
.trigger=${trg}
|
.trigger=${trg}
|
||||||
|
@duplicate=${this._duplicateTrigger}
|
||||||
@value-changed=${this._triggerChanged}
|
@value-changed=${this._triggerChanged}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
></ha-automation-trigger-row>
|
></ha-automation-trigger-row>
|
||||||
@ -68,6 +69,14 @@ export default class HaAutomationTrigger extends LitElement {
|
|||||||
fireEvent(this, "value-changed", { value: triggers });
|
fireEvent(this, "value-changed", { value: triggers });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _duplicateTrigger(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const index = (ev.target as any).index;
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: this.triggers.concat(this.triggers[index]),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
ha-automation-trigger-row,
|
ha-automation-trigger-row,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import "@polymer/paper-input/paper-textarea";
|
import "@polymer/paper-input/paper-textarea";
|
||||||
import { customElement, html, LitElement, property } from "lit-element";
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
|
||||||
import "../../../../../components/entity/ha-entity-picker";
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
import { ForDict, NumericStateTrigger } from "../../../../../data/automation";
|
import { ForDict, NumericStateTrigger } from "../../../../../data/automation";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
@ -19,8 +18,8 @@ export default class HaNumericStateTrigger extends LitElement {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
public render() {
|
||||||
const { value_template, entity_id, below, above } = this.trigger;
|
const { value_template, entity_id, attribute, below, above } = this.trigger;
|
||||||
let trgFor = this.trigger.for;
|
let trgFor = this.trigger.for;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -41,10 +40,22 @@ export default class HaNumericStateTrigger extends LitElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
.value="${entity_id}"
|
.value="${entity_id}"
|
||||||
@value-changed="${this._entityPicked}"
|
@value-changed="${this._valueChanged}"
|
||||||
|
.name=${"entity_id"}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
|
<ha-entity-attribute-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.entityId=${entity_id}
|
||||||
|
.value=${attribute}
|
||||||
|
.name=${"attribute"}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.state.attribute"
|
||||||
|
)}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
allow-custom-value
|
||||||
|
></ha-entity-attribute-picker>
|
||||||
<paper-input
|
<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.type.numeric_state.above"
|
"ui.panel.config.automation.editor.triggers.type.numeric_state.above"
|
||||||
@ -84,13 +95,6 @@ export default class HaNumericStateTrigger extends LitElement {
|
|||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityPicked(ev) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
fireEvent(this, "value-changed", {
|
|
||||||
value: { ...this.trigger, entity_id: ev.detail.value },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { customElement, html, LitElement, property } from "lit-element";
|
import { customElement, html, LitElement, property } from "lit-element";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import "../../../../../components/entity/ha-entity-attribute-picker";
|
||||||
import "../../../../../components/entity/ha-entity-picker";
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
import { ForDict, StateTrigger } from "../../../../../data/automation";
|
import { ForDict, StateTrigger } from "../../../../../data/automation";
|
||||||
import { PolymerChangedEvent } from "../../../../../polymer-types";
|
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import {
|
||||||
handleChangeEvent,
|
handleChangeEvent,
|
||||||
@ -21,7 +20,7 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const { entity_id, to, from } = this.trigger;
|
const { entity_id, attribute, to, from } = this.trigger;
|
||||||
let trgFor = this.trigger.for;
|
let trgFor = this.trigger.for;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
@ -43,10 +42,22 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
return html`
|
return html`
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
.value=${entity_id}
|
.value=${entity_id}
|
||||||
@value-changed=${this._entityPicked}
|
@value-changed=${this._valueChanged}
|
||||||
|
.name=${"entity_id"}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
|
<ha-entity-attribute-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.entityId=${entity_id}
|
||||||
|
.value=${attribute}
|
||||||
|
.name=${"attribute"}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.state.attribute"
|
||||||
|
)}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
allow-custom-value
|
||||||
|
></ha-entity-attribute-picker>
|
||||||
<paper-input
|
<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.type.state.from"
|
"ui.panel.config.automation.editor.triggers.type.state.from"
|
||||||
@ -77,13 +88,6 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityPicked(ev: PolymerChangedEvent<string>) {
|
|
||||||
ev.stopPropagation();
|
|
||||||
fireEvent(this, "value-changed", {
|
|
||||||
value: { ...this.trigger, entity_id: ev.detail.value },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { customElement, html, LitElement, property } from "lit-element";
|
import {
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
internalProperty,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
} from "lit-element";
|
||||||
|
import "../../../../../components/entity/ha-entity-picker";
|
||||||
|
import "../../../../../components/ha-formfield";
|
||||||
|
import "../../../../../components/ha-radio";
|
||||||
import { TimeTrigger } from "../../../../../data/automation";
|
import { TimeTrigger } from "../../../../../data/automation";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import {
|
import {
|
||||||
@ -7,31 +16,81 @@ import {
|
|||||||
TriggerElement,
|
TriggerElement,
|
||||||
} from "../ha-automation-trigger-row";
|
} from "../ha-automation-trigger-row";
|
||||||
|
|
||||||
|
const includeDomains = ["input_datetime"];
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-time")
|
@customElement("ha-automation-trigger-time")
|
||||||
export class HaTimeTrigger extends LitElement implements TriggerElement {
|
export class HaTimeTrigger extends LitElement implements TriggerElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public trigger!: TimeTrigger;
|
@property() public trigger!: TimeTrigger;
|
||||||
|
|
||||||
|
@internalProperty() private _inputMode?: boolean;
|
||||||
|
|
||||||
public static get defaultConfig() {
|
public static get defaultConfig() {
|
||||||
return { at: "" };
|
return { at: "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const { at } = this.trigger;
|
const { at } = this.trigger;
|
||||||
|
const inputMode = this._inputMode ?? at?.startsWith("input_datetime.");
|
||||||
return html`
|
return html`
|
||||||
<paper-input
|
<ha-formfield
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.time.type_value"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-radio
|
||||||
|
@change=${this._handleModeChanged}
|
||||||
|
name="mode"
|
||||||
|
value="value"
|
||||||
|
?checked=${!inputMode}
|
||||||
|
></ha-radio>
|
||||||
|
</ha-formfield>
|
||||||
|
<ha-formfield
|
||||||
|
.label=${this.hass!.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.time.type_input"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-radio
|
||||||
|
@change=${this._handleModeChanged}
|
||||||
|
name="mode"
|
||||||
|
value="input"
|
||||||
|
?checked=${inputMode}
|
||||||
|
></ha-radio>
|
||||||
|
</ha-formfield>
|
||||||
|
${inputMode
|
||||||
|
? html`<ha-entity-picker
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.time.at"
|
||||||
|
)}
|
||||||
|
.includeDomains=${includeDomains}
|
||||||
|
.name=${"at"}
|
||||||
|
.value=${at?.startsWith("input_datetime.") ? at : ""}
|
||||||
|
@value-changed=${this._valueChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-entity-picker>`
|
||||||
|
: html`<paper-input
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
"ui.panel.config.automation.editor.triggers.type.time.at"
|
"ui.panel.config.automation.editor.triggers.type.time.at"
|
||||||
)}
|
)}
|
||||||
name="at"
|
name="at"
|
||||||
.value=${at}
|
.value=${at?.startsWith("input_datetime.") ? "" : at}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></paper-input>
|
></paper-input>`}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleModeChanged(ev: Event) {
|
||||||
|
this._inputMode = (ev.target as any).value === "input";
|
||||||
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
handleChangeEvent(this, ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-trigger-time": HaTimeTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -10,12 +10,13 @@ import {
|
|||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import "../../../common/search/search-input";
|
import "../../../common/search/search-input";
|
||||||
@ -32,6 +33,7 @@ import {
|
|||||||
getConfigEntries,
|
getConfigEntries,
|
||||||
} from "../../../data/config_entries";
|
} from "../../../data/config_entries";
|
||||||
import {
|
import {
|
||||||
|
ATTENTION_SOURCES,
|
||||||
DISCOVERY_SOURCES,
|
DISCOVERY_SOURCES,
|
||||||
getConfigFlowInProgressCollection,
|
getConfigFlowInProgressCollection,
|
||||||
ignoreConfigFlow,
|
ignoreConfigFlow,
|
||||||
@ -355,11 +357,23 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
: ""}
|
: ""}
|
||||||
${configEntriesInProgress.length
|
${configEntriesInProgress.length
|
||||||
? configEntriesInProgress.map(
|
? configEntriesInProgress.map(
|
||||||
(flow: DataEntryFlowProgressExtended) => html`
|
(flow: DataEntryFlowProgressExtended) => {
|
||||||
<ha-card outlined class="discovered">
|
const attention = ATTENTION_SOURCES.includes(
|
||||||
|
flow.context.source
|
||||||
|
);
|
||||||
|
return html`
|
||||||
|
<ha-card
|
||||||
|
outlined
|
||||||
|
class=${classMap({
|
||||||
|
discovered: !attention,
|
||||||
|
attention: attention,
|
||||||
|
})}
|
||||||
|
>
|
||||||
<div class="header">
|
<div class="header">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.integrations.discovered"
|
`ui.panel.config.integrations.${
|
||||||
|
attention ? "attention" : "discovered"
|
||||||
|
}`
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
@ -381,7 +395,9 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
.flowId=${flow.flow_id}
|
.flowId=${flow.flow_id}
|
||||||
>
|
>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.integrations.configure"
|
`ui.panel.config.integrations.${
|
||||||
|
attention ? "reconfigure" : "configure"
|
||||||
|
}`
|
||||||
)}
|
)}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
${DISCOVERY_SOURCES.includes(flow.context.source) &&
|
${DISCOVERY_SOURCES.includes(flow.context.source) &&
|
||||||
@ -400,7 +416,8 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`
|
`;
|
||||||
|
}
|
||||||
)
|
)
|
||||||
: ""}
|
: ""}
|
||||||
${groupedConfigEntries.size
|
${groupedConfigEntries.size
|
||||||
@ -639,6 +656,18 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
.attention {
|
||||||
|
--ha-card-border-color: var(--error-color);
|
||||||
|
}
|
||||||
|
.attention .header {
|
||||||
|
background: var(--error-color);
|
||||||
|
color: var(--text-primary-color);
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.attention mwc-button {
|
||||||
|
--mdc-theme-primary: var(--error-color);
|
||||||
|
}
|
||||||
.discovered {
|
.discovered {
|
||||||
--ha-card-border-color: var(--primary-color);
|
--ha-card-border-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
|
|
||||||
private _renderSingleEntry(item: ConfigEntryExtended): TemplateResult {
|
private _renderSingleEntry(item: ConfigEntryExtended): TemplateResult {
|
||||||
const devices = this._getDevices(item);
|
const devices = this._getDevices(item);
|
||||||
|
const services = this._getServices(item);
|
||||||
const entities = this._getEntities(item);
|
const entities = this._getEntities(item);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
@ -168,7 +169,7 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
<h3>
|
<h3>
|
||||||
${item.localized_domain_name === item.title ? "" : item.title}
|
${item.localized_domain_name === item.title ? "" : item.title}
|
||||||
</h3>
|
</h3>
|
||||||
${devices.length || entities.length
|
${devices.length || services.length || entities.length
|
||||||
? html`
|
? html`
|
||||||
<div>
|
<div>
|
||||||
${devices.length
|
${devices.length
|
||||||
@ -180,10 +181,22 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
"count",
|
"count",
|
||||||
devices.length
|
devices.length
|
||||||
)}</a
|
)}</a
|
||||||
|
>${services.length ? "," : ""}
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
${services.length
|
||||||
|
? html`
|
||||||
|
<a
|
||||||
|
href=${`/config/devices/dashboard?historyBack=1&config_entry=${item.entry_id}`}
|
||||||
|
>${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.services",
|
||||||
|
"count",
|
||||||
|
services.length
|
||||||
|
)}</a
|
||||||
>
|
>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
${devices.length && entities.length
|
${(devices.length || services.length) && entities.length
|
||||||
? this.hass.localize("ui.common.and")
|
? this.hass.localize("ui.common.and")
|
||||||
: ""}
|
: ""}
|
||||||
${entities.length
|
${entities.length
|
||||||
@ -304,8 +317,21 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
if (!this.deviceRegistryEntries) {
|
if (!this.deviceRegistryEntries) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
return this.deviceRegistryEntries.filter((device) =>
|
return this.deviceRegistryEntries.filter(
|
||||||
device.config_entries.includes(configEntry.entry_id)
|
(device) =>
|
||||||
|
device.config_entries.includes(configEntry.entry_id) &&
|
||||||
|
device.entry_type !== "service"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _getServices(configEntry: ConfigEntry): DeviceRegistryEntry[] {
|
||||||
|
if (!this.deviceRegistryEntries) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.deviceRegistryEntries.filter(
|
||||||
|
(device) =>
|
||||||
|
device.config_entries.includes(configEntry.entry_id) &&
|
||||||
|
device.entry_type === "service"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ class HaLogbook extends LitElement {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 65px;
|
width: 70px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: var(--secondary-text-color);
|
color: var(--secondary-text-color);
|
||||||
|
@ -44,6 +44,8 @@ class ActionHandler extends HTMLElement implements ActionHandler {
|
|||||||
|
|
||||||
protected held = false;
|
protected held = false;
|
||||||
|
|
||||||
|
private cancelled = false;
|
||||||
|
|
||||||
private dblClickTimeout?: number;
|
private dblClickTimeout?: number;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -76,9 +78,12 @@ class ActionHandler extends HTMLElement implements ActionHandler {
|
|||||||
document.addEventListener(
|
document.addEventListener(
|
||||||
ev,
|
ev,
|
||||||
() => {
|
() => {
|
||||||
clearTimeout(this.timer);
|
this.cancelled = true;
|
||||||
|
if (this.timer) {
|
||||||
this.stopAnimation();
|
this.stopAnimation();
|
||||||
|
clearTimeout(this.timer);
|
||||||
this.timer = undefined;
|
this.timer = undefined;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ passive: true }
|
{ passive: true }
|
||||||
);
|
);
|
||||||
@ -124,7 +129,7 @@ class ActionHandler extends HTMLElement implements ActionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
element.actionHandler.start = (ev: Event) => {
|
element.actionHandler.start = (ev: Event) => {
|
||||||
this.held = false;
|
this.cancelled = false;
|
||||||
let x;
|
let x;
|
||||||
let y;
|
let y;
|
||||||
if ((ev as TouchEvent).touches) {
|
if ((ev as TouchEvent).touches) {
|
||||||
@ -136,6 +141,7 @@ class ActionHandler extends HTMLElement implements ActionHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.hasHold) {
|
if (options.hasHold) {
|
||||||
|
this.held = false;
|
||||||
this.timer = window.setTimeout(() => {
|
this.timer = window.setTimeout(() => {
|
||||||
this.startAnimation(x, y);
|
this.startAnimation(x, y);
|
||||||
this.held = true;
|
this.held = true;
|
||||||
@ -144,24 +150,20 @@ class ActionHandler extends HTMLElement implements ActionHandler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
element.actionHandler.end = (ev: Event) => {
|
element.actionHandler.end = (ev: Event) => {
|
||||||
// Don't respond on our own generated click
|
// Don't respond when moved or scrolled while touch
|
||||||
if (!ev.isTrusted) {
|
if (["touchend", "touchcancel"].includes(ev.type) && this.cancelled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Prevent mouse event if touch event
|
// Prevent mouse event if touch event
|
||||||
|
if (ev.cancelable) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
if (options.hasHold) {
|
|
||||||
if (
|
|
||||||
["touchend", "touchcancel"].includes(ev.type) &&
|
|
||||||
this.timer === undefined
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
if (options.hasHold) {
|
||||||
clearTimeout(this.timer);
|
clearTimeout(this.timer);
|
||||||
this.stopAnimation();
|
this.stopAnimation();
|
||||||
this.timer = undefined;
|
this.timer = undefined;
|
||||||
}
|
}
|
||||||
if (this.held) {
|
if (options.hasHold && this.held) {
|
||||||
fireEvent(element, "action", { action: "hold" });
|
fireEvent(element, "action", { action: "hold" });
|
||||||
} else if (options.hasDoubleClick) {
|
} else if (options.hasDoubleClick) {
|
||||||
if (
|
if (
|
||||||
@ -179,8 +181,6 @@ class ActionHandler extends HTMLElement implements ActionHandler {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fireEvent(element, "action", { action: "tap" });
|
fireEvent(element, "action", { action: "tap" });
|
||||||
// Fire the click we prevented the action for
|
|
||||||
(ev.target as HTMLElement)?.click();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,27 +1,51 @@
|
|||||||
import "../../../components/ha-icon-button";
|
import { mdiDrag } from "@mdi/js";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import { guard } from "lit-html/directives/guard";
|
||||||
|
import type { SortableEvent } from "sortablejs";
|
||||||
|
import Sortable, {
|
||||||
|
AutoScroll,
|
||||||
|
OnSpill,
|
||||||
|
} from "sortablejs/modular/sortable.core.esm";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import "../../../components/entity/ha-entity-picker";
|
import "../../../components/entity/ha-entity-picker";
|
||||||
|
import "../../../components/ha-icon-button";
|
||||||
|
import { sortableStyles } from "../../../resources/ha-sortable-style";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { EditorTarget } from "../editor/types";
|
import { EditorTarget } from "../editor/types";
|
||||||
import { EntityConfig } from "../entity-rows/types";
|
import { EntityConfig } from "../entity-rows/types";
|
||||||
|
|
||||||
@customElement("hui-entity-editor")
|
@customElement("hui-entity-editor")
|
||||||
export class HuiEntityEditor extends LitElement {
|
export class HuiEntityEditor extends LitElement {
|
||||||
@property() protected hass?: HomeAssistant;
|
@property({ attribute: false }) protected hass?: HomeAssistant;
|
||||||
|
|
||||||
@property() protected entities?: EntityConfig[];
|
@property({ attribute: false }) protected entities?: EntityConfig[];
|
||||||
|
|
||||||
@property() protected label?: string;
|
@property() protected label?: string;
|
||||||
|
|
||||||
|
@internalProperty() private _attached = false;
|
||||||
|
|
||||||
|
private _sortable?;
|
||||||
|
|
||||||
|
public connectedCallback() {
|
||||||
|
super.connectedCallback();
|
||||||
|
this._attached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._attached = false;
|
||||||
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
if (!this.entities) {
|
if (!this.entities) {
|
||||||
return html``;
|
return html``;
|
||||||
@ -36,42 +60,73 @@ export class HuiEntityEditor extends LitElement {
|
|||||||
")"}
|
")"}
|
||||||
</h3>
|
</h3>
|
||||||
<div class="entities">
|
<div class="entities">
|
||||||
${this.entities.map((entityConf, index) => {
|
${guard([this.entities], () =>
|
||||||
|
this.entities!.map((entityConf, index) => {
|
||||||
return html`
|
return html`
|
||||||
<div class="entity">
|
<div class="entity" data-entity-id=${entityConf.entity}>
|
||||||
|
<ha-svg-icon .path=${mdiDrag}></ha-svg-icon>
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value="${entityConf.entity}"
|
.value=${entityConf.entity}
|
||||||
.index="${index}"
|
.index=${index}
|
||||||
@change="${this._valueChanged}"
|
@change=${this._valueChanged}
|
||||||
allow-custom-entity
|
allow-custom-entity
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
<ha-icon-button
|
|
||||||
title="Move entity down"
|
|
||||||
icon="hass:arrow-down"
|
|
||||||
.index="${index}"
|
|
||||||
@click="${this._entityDown}"
|
|
||||||
?disabled="${index === this.entities!.length - 1}"
|
|
||||||
></ha-icon-button>
|
|
||||||
<ha-icon-button
|
|
||||||
title="Move entity up"
|
|
||||||
icon="hass:arrow-up"
|
|
||||||
.index="${index}"
|
|
||||||
@click="${this._entityUp}"
|
|
||||||
?disabled="${index === 0}"
|
|
||||||
></ha-icon-button>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
})}
|
})
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<ha-entity-picker
|
<ha-entity-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@change="${this._addEntity}"
|
@change=${this._addEntity}
|
||||||
></ha-entity-picker>
|
></ha-entity-picker>
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _addEntity(ev: Event): void {
|
protected firstUpdated(): void {
|
||||||
|
Sortable.mount(OnSpill);
|
||||||
|
Sortable.mount(new AutoScroll());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated(changedProps: PropertyValues): void {
|
||||||
|
super.updated(changedProps);
|
||||||
|
|
||||||
|
const attachedChanged = changedProps.has("_attached");
|
||||||
|
const entitiesChanged = changedProps.has("entities");
|
||||||
|
|
||||||
|
if (!entitiesChanged && !attachedChanged) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachedChanged && !this._attached) {
|
||||||
|
// Tear down sortable, if available
|
||||||
|
this._sortable?.destroy();
|
||||||
|
this._sortable = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._sortable && this.entities) {
|
||||||
|
this._createSortable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entitiesChanged) {
|
||||||
|
this._sortable.sort(this.entities?.map((entity) => entity.entity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _createSortable() {
|
||||||
|
this._sortable = new Sortable(this.shadowRoot!.querySelector(".entities"), {
|
||||||
|
animation: 150,
|
||||||
|
fallbackClass: "sortable-fallback",
|
||||||
|
handle: "ha-svg-icon",
|
||||||
|
dataIdAttr: "data-entity-id",
|
||||||
|
onEnd: async (evt: SortableEvent) => this._entityMoved(evt),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _addEntity(ev: Event): Promise<void> {
|
||||||
const target = ev.target! as EditorTarget;
|
const target = ev.target! as EditorTarget;
|
||||||
if (target.value === "") {
|
if (target.value === "") {
|
||||||
return;
|
return;
|
||||||
@ -83,26 +138,14 @@ export class HuiEntityEditor extends LitElement {
|
|||||||
fireEvent(this, "entities-changed", { entities: newConfigEntities });
|
fireEvent(this, "entities-changed", { entities: newConfigEntities });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityUp(ev: Event): void {
|
private _entityMoved(ev: SortableEvent): void {
|
||||||
const target = ev.target! as EditorTarget;
|
if (ev.oldIndex === ev.newIndex) {
|
||||||
const newEntities = this.entities!.concat();
|
return;
|
||||||
|
|
||||||
[newEntities[target.index! - 1], newEntities[target.index!]] = [
|
|
||||||
newEntities[target.index!],
|
|
||||||
newEntities[target.index! - 1],
|
|
||||||
];
|
|
||||||
|
|
||||||
fireEvent(this, "entities-changed", { entities: newEntities });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _entityDown(ev: Event): void {
|
|
||||||
const target = ev.target! as EditorTarget;
|
|
||||||
const newEntities = this.entities!.concat();
|
const newEntities = this.entities!.concat();
|
||||||
|
|
||||||
[newEntities[target.index! + 1], newEntities[target.index!]] = [
|
newEntities.splice(ev.newIndex!, 0, newEntities.splice(ev.oldIndex!, 1)[0]);
|
||||||
newEntities[target.index!],
|
|
||||||
newEntities[target.index! + 1],
|
|
||||||
];
|
|
||||||
|
|
||||||
fireEvent(this, "entities-changed", { entities: newEntities });
|
fireEvent(this, "entities-changed", { entities: newEntities });
|
||||||
}
|
}
|
||||||
@ -123,16 +166,23 @@ export class HuiEntityEditor extends LitElement {
|
|||||||
fireEvent(this, "entities-changed", { entities: newConfigEntities });
|
fireEvent(this, "entities-changed", { entities: newConfigEntities });
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult[] {
|
||||||
return css`
|
return [
|
||||||
|
sortableStyles,
|
||||||
|
css`
|
||||||
.entity {
|
.entity {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: center;
|
||||||
|
}
|
||||||
|
.entity ha-svg-icon {
|
||||||
|
padding-right: 8px;
|
||||||
|
cursor: move;
|
||||||
}
|
}
|
||||||
.entity ha-entity-picker {
|
.entity ha-entity-picker {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
`;
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +171,7 @@ export class HuiCreateDialogCard extends LitElement implements HassDialog {
|
|||||||
ha-dialog {
|
ha-dialog {
|
||||||
--mdc-dialog-max-width: 845px;
|
--mdc-dialog-max-width: 845px;
|
||||||
--dialog-content-padding: 2px 24px 20px 24px;
|
--dialog-content-padding: 2px 24px 20px 24px;
|
||||||
|
--dialog-z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-dialog.table {
|
ha-dialog.table {
|
||||||
|
@ -366,6 +366,7 @@ export class HuiDialogEditCard extends LitElement implements HassDialog {
|
|||||||
|
|
||||||
ha-dialog {
|
ha-dialog {
|
||||||
--mdc-dialog-max-width: 845px;
|
--mdc-dialog-max-width: 845px;
|
||||||
|
--dialog-z-index: 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-header-bar {
|
ha-header-bar {
|
||||||
|
@ -140,6 +140,7 @@ export class HuiDialogSuggestCard extends LitElement {
|
|||||||
}
|
}
|
||||||
ha-paper-dialog {
|
ha-paper-dialog {
|
||||||
max-width: 845px;
|
max-width: 845px;
|
||||||
|
--dialog-z-index: 5;
|
||||||
}
|
}
|
||||||
mwc-button ha-circular-progress {
|
mwc-button ha-circular-progress {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
|
@ -2,13 +2,15 @@ import "@polymer/paper-input/paper-input";
|
|||||||
import {
|
import {
|
||||||
customElement,
|
customElement,
|
||||||
html,
|
html,
|
||||||
|
internalProperty,
|
||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
|
import { assert, object, optional, string } from "superstruct";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { stateIcon } from "../../../../common/entity/state_icon";
|
import { stateIcon } from "../../../../common/entity/state_icon";
|
||||||
|
import "../../../../components/entity/ha-entity-attribute-picker";
|
||||||
import "../../../../components/ha-icon-input";
|
import "../../../../components/ha-icon-input";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import { EntityCardConfig } from "../../cards/types";
|
import { EntityCardConfig } from "../../cards/types";
|
||||||
@ -19,7 +21,6 @@ import { headerFooterConfigStructs } from "../../header-footer/types";
|
|||||||
import { LovelaceCardEditor } from "../../types";
|
import { LovelaceCardEditor } from "../../types";
|
||||||
import { EditorTarget, EntitiesEditorEvent } from "../types";
|
import { EditorTarget, EntitiesEditorEvent } from "../types";
|
||||||
import { configElementStyle } from "./config-elements-style";
|
import { configElementStyle } from "./config-elements-style";
|
||||||
import { string, object, optional, assert } from "superstruct";
|
|
||||||
|
|
||||||
const cardConfigStruct = object({
|
const cardConfigStruct = object({
|
||||||
type: string(),
|
type: string(),
|
||||||
@ -113,7 +114,9 @@ export class HuiEntityCardEditor extends LitElement
|
|||||||
></ha-icon-input>
|
></ha-icon-input>
|
||||||
</div>
|
</div>
|
||||||
<div class="side-by-side">
|
<div class="side-by-side">
|
||||||
<paper-input
|
<ha-entity-attribute-picker
|
||||||
|
.hass=${this.hass}
|
||||||
|
.entityId=${this._entity}
|
||||||
.label="${this.hass.localize(
|
.label="${this.hass.localize(
|
||||||
"ui.panel.lovelace.editor.card.generic.attribute"
|
"ui.panel.lovelace.editor.card.generic.attribute"
|
||||||
)} (${this.hass.localize(
|
)} (${this.hass.localize(
|
||||||
@ -122,7 +125,7 @@ export class HuiEntityCardEditor extends LitElement
|
|||||||
.value=${this._attribute}
|
.value=${this._attribute}
|
||||||
.configValue=${"attribute"}
|
.configValue=${"attribute"}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
></paper-input>
|
></ha-entity-attribute-picker>
|
||||||
<paper-input
|
<paper-input
|
||||||
.label="${this.hass.localize(
|
.label="${this.hass.localize(
|
||||||
"ui.panel.lovelace.editor.card.generic.unit"
|
"ui.panel.lovelace.editor.card.generic.unit"
|
||||||
|
@ -13,6 +13,7 @@ import { fireEvent } from "../../common/dom/fire_event";
|
|||||||
import { createCloseHeading } from "../../components/ha-dialog";
|
import { createCloseHeading } from "../../components/ha-dialog";
|
||||||
import { BROWSER_SOURCE } from "../../data/media-player";
|
import { BROWSER_SOURCE } from "../../data/media-player";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { haStyleDialog } from "../../resources/styles";
|
||||||
import type { SelectMediaPlayerDialogParams } from "./show-select-media-source-dialog";
|
import type { SelectMediaPlayerDialogParams } from "./show-select-media-source-dialog";
|
||||||
|
|
||||||
@customElement("hui-dialog-select-media-player")
|
@customElement("hui-dialog-select-media-player")
|
||||||
@ -74,15 +75,18 @@ export class HuiDialogSelectMediaPlayer extends LitElement {
|
|||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult[] {
|
||||||
return css`
|
return [
|
||||||
|
haStyleDialog,
|
||||||
|
css`
|
||||||
ha-dialog {
|
ha-dialog {
|
||||||
--dialog-content-padding: 0 24px 20px;
|
--dialog-content-padding: 0 24px 20px;
|
||||||
}
|
}
|
||||||
paper-item {
|
paper-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
`;
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import { fireEvent } from "../../common/dom/fire_event";
|
|||||||
import { createCloseHeading } from "../../components/ha-dialog";
|
import { createCloseHeading } from "../../components/ha-dialog";
|
||||||
import "../../components/ha-hls-player";
|
import "../../components/ha-hls-player";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
|
import { haStyleDialog } from "../../resources/styles";
|
||||||
import { WebBrowserPlayMediaDialogParams } from "./show-media-player-dialog";
|
import { WebBrowserPlayMediaDialogParams } from "./show-media-player-dialog";
|
||||||
|
|
||||||
@customElement("hui-dialog-web-browser-play-media")
|
@customElement("hui-dialog-web-browser-play-media")
|
||||||
@ -92,12 +93,10 @@ export class HuiDialogWebBrowserPlayMedia extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult[] {
|
||||||
return css`
|
return [
|
||||||
ha-dialog {
|
haStyleDialog,
|
||||||
--mdc-dialog-heading-ink-color: var(--primary-text-color);
|
css`
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 800px) {
|
@media (min-width: 800px) {
|
||||||
ha-dialog {
|
ha-dialog {
|
||||||
--mdc-dialog-max-width: 800px;
|
--mdc-dialog-max-width: 800px;
|
||||||
@ -111,7 +110,8 @@ export class HuiDialogWebBrowserPlayMedia extends LitElement {
|
|||||||
outline: none;
|
outline: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
`;
|
`,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
75
src/resources/ha-sortable-style.ts
Normal file
75
src/resources/ha-sortable-style.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { css } from "lit-element";
|
||||||
|
|
||||||
|
export const sortableStyles = css`
|
||||||
|
#sortable a:nth-of-type(2n) paper-icon-item {
|
||||||
|
animation-name: keyframes1;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
transform-origin: 50% 10%;
|
||||||
|
animation-delay: -0.75s;
|
||||||
|
animation-duration: 0.25s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable a:nth-of-type(2n-1) paper-icon-item {
|
||||||
|
animation-name: keyframes2;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
animation-direction: alternate;
|
||||||
|
transform-origin: 30% 5%;
|
||||||
|
animation-delay: -0.5s;
|
||||||
|
animation-duration: 0.33s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sortable {
|
||||||
|
outline: none;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable-ghost {
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable-fallback {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes keyframes1 {
|
||||||
|
0% {
|
||||||
|
transform: rotate(-1deg);
|
||||||
|
animation-timing-function: ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: rotate(1.5deg);
|
||||||
|
animation-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes keyframes2 {
|
||||||
|
0% {
|
||||||
|
transform: rotate(1deg);
|
||||||
|
animation-timing-function: ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: rotate(-1.5deg);
|
||||||
|
animation-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hide-panel {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([expanded]) .hide-panel {
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
paper-icon-item.hidden-panel,
|
||||||
|
paper-icon-item.hidden-panel span,
|
||||||
|
paper-icon-item.hidden-panel ha-icon[slot="item-icon"] {
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`;
|
@ -88,9 +88,15 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const themeMeta = document.querySelector("meta[name=theme-color]");
|
const themeMeta = document.querySelector("meta[name=theme-color]");
|
||||||
const headerColor = getComputedStyle(
|
const computedStyles = getComputedStyle(document.documentElement);
|
||||||
document.documentElement
|
const headerColor = computedStyles.getPropertyValue(
|
||||||
).getPropertyValue("--app-header-background-color");
|
"--app-header-background-color"
|
||||||
|
);
|
||||||
|
|
||||||
|
document.documentElement.style.backgroundColor = computedStyles.getPropertyValue(
|
||||||
|
"--primary-background-color"
|
||||||
|
);
|
||||||
|
|
||||||
if (themeMeta) {
|
if (themeMeta) {
|
||||||
if (!themeMeta.hasAttribute("default-content")) {
|
if (!themeMeta.hasAttribute("default-content")) {
|
||||||
themeMeta.setAttribute(
|
themeMeta.setAttribute(
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
|
import { UpdatingElement } from "lit-element";
|
||||||
|
import { HASSDomEvent } from "../common/dom/fire_event";
|
||||||
import {
|
import {
|
||||||
closeDialog,
|
closeDialog,
|
||||||
showDialog,
|
|
||||||
DialogState,
|
|
||||||
DialogClosedParams,
|
DialogClosedParams,
|
||||||
|
DialogState,
|
||||||
|
showDialog,
|
||||||
} from "../dialogs/make-dialog-manager";
|
} from "../dialogs/make-dialog-manager";
|
||||||
import { Constructor } from "../types";
|
|
||||||
import { HASSDomEvent } from "../common/dom/fire_event";
|
|
||||||
import { UpdatingElement } from "lit-element";
|
|
||||||
import { ProvideHassElement } from "../mixins/provide-hass-lit-mixin";
|
import { ProvideHassElement } from "../mixins/provide-hass-lit-mixin";
|
||||||
|
import { Constructor } from "../types";
|
||||||
|
|
||||||
const DEBUG = false;
|
const DEBUG = false;
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"mailbox": "Mailbox",
|
"mailbox": "Mailbox",
|
||||||
"shopping_list": "Shopping list",
|
"shopping_list": "Shopping list",
|
||||||
"developer_tools": "Developer Tools",
|
"developer_tools": "Developer Tools",
|
||||||
|
"media_browser": "Media Browser",
|
||||||
"profile": "Profile"
|
"profile": "Profile"
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
@ -285,6 +286,10 @@
|
|||||||
"entity": "Entity",
|
"entity": "Entity",
|
||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"show_entities": "Show entities"
|
"show_entities": "Show entities"
|
||||||
|
},
|
||||||
|
"entity-attribute-picker": {
|
||||||
|
"attribute": "Attribute",
|
||||||
|
"show_attributes": "Show attributes"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"device-picker": {
|
"device-picker": {
|
||||||
@ -364,6 +369,7 @@
|
|||||||
"audio_not_supported": "Your browser does not support the audio element.",
|
"audio_not_supported": "Your browser does not support the audio element.",
|
||||||
"video_not_supported": "Your browser does not support the video element.",
|
"video_not_supported": "Your browser does not support the video element.",
|
||||||
"media_not_supported": "The Browser Media Player does not support this type of media",
|
"media_not_supported": "The Browser Media Player does not support this type of media",
|
||||||
|
"media_browsing_error": "Media Browsing Error",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"server": "Server",
|
"server": "Server",
|
||||||
"library": "Library",
|
"library": "Library",
|
||||||
@ -913,6 +919,8 @@
|
|||||||
"show_info_automation": "Show info about automation",
|
"show_info_automation": "Show info about automation",
|
||||||
"delete_automation": "Delete automation",
|
"delete_automation": "Delete automation",
|
||||||
"delete_confirm": "Are you sure you want to delete this automation?",
|
"delete_confirm": "Are you sure you want to delete this automation?",
|
||||||
|
"duplicate_automation": "Duplicate automation",
|
||||||
|
"duplicate": "Duplicate",
|
||||||
"headers": {
|
"headers": {
|
||||||
"name": "Name"
|
"name": "Name"
|
||||||
}
|
}
|
||||||
@ -983,6 +991,7 @@
|
|||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"label": "State",
|
"label": "State",
|
||||||
|
"attribute": "Attribute (Optional)",
|
||||||
"from": "From",
|
"from": "From",
|
||||||
"for": "For",
|
"for": "For",
|
||||||
"to": "To"
|
"to": "To"
|
||||||
@ -1019,8 +1028,10 @@
|
|||||||
"value_template": "Value template"
|
"value_template": "Value template"
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
|
"type_value": "Fixed time",
|
||||||
|
"type_input": "Value of a date/time helper",
|
||||||
"label": "Time",
|
"label": "Time",
|
||||||
"at": "At"
|
"at": "At time"
|
||||||
},
|
},
|
||||||
"time_pattern": {
|
"time_pattern": {
|
||||||
"label": "Time Pattern",
|
"label": "Time Pattern",
|
||||||
@ -1096,6 +1107,8 @@
|
|||||||
"value_template": "[%key:ui::panel::config::automation::editor::triggers::type::template::value_template%]"
|
"value_template": "[%key:ui::panel::config::automation::editor::triggers::type::template::value_template%]"
|
||||||
},
|
},
|
||||||
"time": {
|
"time": {
|
||||||
|
"type_value": "[%key:ui::panel::config::automation::editor::triggers::type::time::type_value%]",
|
||||||
|
"type_input": "[%key:ui::panel::config::automation::editor::triggers::type::time::type_input%]",
|
||||||
"label": "[%key:ui::panel::config::automation::editor::triggers::type::time::label%]",
|
"label": "[%key:ui::panel::config::automation::editor::triggers::type::time::label%]",
|
||||||
"after": "After",
|
"after": "After",
|
||||||
"before": "Before"
|
"before": "Before"
|
||||||
@ -1130,7 +1143,13 @@
|
|||||||
"wait_template": {
|
"wait_template": {
|
||||||
"label": "Wait",
|
"label": "Wait",
|
||||||
"wait_template": "Wait Template",
|
"wait_template": "Wait Template",
|
||||||
"timeout": "Timeout (optional)"
|
"timeout": "Timeout (optional)",
|
||||||
|
"continue_timeout": "Continue on timeout"
|
||||||
|
},
|
||||||
|
"wait_for_trigger": {
|
||||||
|
"label": "Wait for trigger",
|
||||||
|
"timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::timeout%]",
|
||||||
|
"continue_timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::continue_timeout%]"
|
||||||
},
|
},
|
||||||
"condition": {
|
"condition": {
|
||||||
"label": "Condition"
|
"label": "Condition"
|
||||||
@ -1608,6 +1627,7 @@
|
|||||||
"description": "Manage integrations",
|
"description": "Manage integrations",
|
||||||
"integration": "integration",
|
"integration": "integration",
|
||||||
"discovered": "Discovered",
|
"discovered": "Discovered",
|
||||||
|
"attention": "Attention required",
|
||||||
"configured": "Configured",
|
"configured": "Configured",
|
||||||
"new": "Set up a new integration",
|
"new": "Set up a new integration",
|
||||||
"add_integration": "Add integration",
|
"add_integration": "Add integration",
|
||||||
@ -1616,6 +1636,7 @@
|
|||||||
"note_about_website_reference": "More are available on the ",
|
"note_about_website_reference": "More are available on the ",
|
||||||
"home_assistant_website": "Home Assistant website",
|
"home_assistant_website": "Home Assistant website",
|
||||||
"configure": "Configure",
|
"configure": "Configure",
|
||||||
|
"reconfigure": "Reconfigure",
|
||||||
"none": "Nothing configured yet",
|
"none": "Nothing configured yet",
|
||||||
"none_found": "No integrations found",
|
"none_found": "No integrations found",
|
||||||
"none_found_detail": "Adjust your search criteria.",
|
"none_found_detail": "Adjust your search criteria.",
|
||||||
@ -1638,6 +1659,7 @@
|
|||||||
"config_entry": {
|
"config_entry": {
|
||||||
"devices": "{count} {count, plural,\n one {device}\n other {devices}\n}",
|
"devices": "{count} {count, plural,\n one {device}\n other {devices}\n}",
|
||||||
"entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}",
|
"entities": "{count} {count, plural,\n one {entity}\n other {entities}\n}",
|
||||||
|
"services": "{count} {count, plural,\n one {service}\n other {services}\n}",
|
||||||
"rename": "Rename",
|
"rename": "Rename",
|
||||||
"options": "Options",
|
"options": "Options",
|
||||||
"system_options": "System options",
|
"system_options": "System options",
|
||||||
|
@ -505,6 +505,7 @@
|
|||||||
"back": "Zpět",
|
"back": "Zpět",
|
||||||
"cancel": "Zrušit",
|
"cancel": "Zrušit",
|
||||||
"close": "Zavřít",
|
"close": "Zavřít",
|
||||||
|
"continue": "Pokračovat",
|
||||||
"delete": "Smazat",
|
"delete": "Smazat",
|
||||||
"error_required": "Povinné",
|
"error_required": "Povinné",
|
||||||
"loading": "Načítání",
|
"loading": "Načítání",
|
||||||
@ -562,6 +563,8 @@
|
|||||||
"no_history_found": "Historie stavu chybí."
|
"no_history_found": "Historie stavu chybí."
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "Váš prohlížeč nepodporuje element \"audio\".",
|
||||||
|
"choose_player": "Vyberte přehrávač",
|
||||||
"choose-source": "Zvolte zdroj",
|
"choose-source": "Zvolte zdroj",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "Album",
|
"album": "Album",
|
||||||
@ -570,12 +573,16 @@
|
|||||||
"playlist": "Seznam skladeb",
|
"playlist": "Seznam skladeb",
|
||||||
"server": "Server"
|
"server": "Server"
|
||||||
},
|
},
|
||||||
|
"media_not_supported": "Přehrávač médií v prohlížeči nepodporuje tento typ média",
|
||||||
|
"media_player": "Přehrávač médií",
|
||||||
"media-player-browser": "Prohlížeč přehrávače médií",
|
"media-player-browser": "Prohlížeč přehrávače médií",
|
||||||
"no_items": "Žádné položky",
|
"no_items": "Žádné položky",
|
||||||
"pick": "Vybrat",
|
"pick": "Vybrat",
|
||||||
"pick-media": "Vybrat média",
|
"pick-media": "Vybrat média",
|
||||||
"play": "Přehrát",
|
"play": "Přehrát",
|
||||||
"play-media": "Přehrát média"
|
"play-media": "Přehrát média",
|
||||||
|
"video_not_supported": "Váš prohlížeč nepodporuje element \"video\".",
|
||||||
|
"web-browser": "Webový prohlížeč"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Obrázek",
|
"label": "Obrázek",
|
||||||
@ -633,7 +640,7 @@
|
|||||||
"icon": "Nahrazení ikony",
|
"icon": "Nahrazení ikony",
|
||||||
"icon_error": "Ikony by měly být ve formátu 'prefix:nazevikony', např. 'mdi:home'",
|
"icon_error": "Ikony by měly být ve formátu 'prefix:nazevikony', např. 'mdi:home'",
|
||||||
"name": "Přepsání názvu",
|
"name": "Přepsání názvu",
|
||||||
"note": "Poznámka: to nemusí fungovat se všemi integracemi.",
|
"note": "Poznámka: U všech integrací to ještě nemusí fungovat.",
|
||||||
"unavailable": "Tato entita není momentálně k dispozici.",
|
"unavailable": "Tato entita není momentálně k dispozici.",
|
||||||
"update": "Aktualizovat"
|
"update": "Aktualizovat"
|
||||||
},
|
},
|
||||||
@ -689,8 +696,10 @@
|
|||||||
"crop": "Oříznout"
|
"crop": "Oříznout"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "Ovládací prvky",
|
||||||
"dismiss": "Zavřít dialog",
|
"dismiss": "Zavřít dialog",
|
||||||
"edit": "Upravit entitu",
|
"edit": "Upravit entitu",
|
||||||
|
"history": "Historie",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Vytvořit zónu z aktuálního umístění"
|
"create_zone": "Vytvořit zónu z aktuálního umístění"
|
||||||
},
|
},
|
||||||
@ -1543,6 +1552,7 @@
|
|||||||
"reload_restart_confirm": "Restartujte Home Assistant pro nové načtení této integrace",
|
"reload_restart_confirm": "Restartujte Home Assistant pro nové načtení této integrace",
|
||||||
"rename": "Přejmenovat",
|
"rename": "Přejmenovat",
|
||||||
"restart_confirm": "Restartujte Home Assistant pro odstranění této integrace",
|
"restart_confirm": "Restartujte Home Assistant pro odstranění této integrace",
|
||||||
|
"services": "{count} {count, plural,\n one {služba}\n few {služby}\n other {služeb}\n}",
|
||||||
"settings_button": "Upravit nastavení pro {integration}",
|
"settings_button": "Upravit nastavení pro {integration}",
|
||||||
"system_options": "Více možností",
|
"system_options": "Více možností",
|
||||||
"system_options_button": "Upravit nastavení pro {integration}",
|
"system_options_button": "Upravit nastavení pro {integration}",
|
||||||
@ -1762,8 +1772,21 @@
|
|||||||
"versions": "Získávám informace o verzích firmwaru a typech příkazů",
|
"versions": "Získávám informace o verzích firmwaru a typech příkazů",
|
||||||
"wakeup": "Nastavuji podporu pro probouzecí fronty a zprávy"
|
"wakeup": "Nastavuji podporu pro probouzecí fronty a zprávy"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "Podrobnosti uzlu",
|
||||||
|
"not_found": "Uzel nenalezen"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "Selhalo",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "Výrobce",
|
||||||
|
"model": "Model",
|
||||||
|
"query_stage": "Fáze dotazu",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "Pokud je uzel napájen z baterie, nezapomeňte jej probudit, než budete pokračovat",
|
"battery_note": "Pokud je uzel napájen z baterie, nezapomeňte jej probudit, než budete pokračovat",
|
||||||
|
"button": "Obnovit uzel",
|
||||||
"complete": "Obnova uzlu dokončena",
|
"complete": "Obnova uzlu dokončena",
|
||||||
"description": "Toto řekne OpenZWave, aby znovu provedl komunikaci s uzlem a aktualizoval typy příkazů, schopnosti a hodnoty uzlu.",
|
"description": "Toto řekne OpenZWave, aby znovu provedl komunikaci s uzlem a aktualizoval typy příkazů, schopnosti a hodnoty uzlu.",
|
||||||
"node_status": "Stav uzlu",
|
"node_status": "Stav uzlu",
|
||||||
@ -1912,7 +1935,7 @@
|
|||||||
"filter": "Nově načíst entity integrace Filter",
|
"filter": "Nově načíst entity integrace Filter",
|
||||||
"generic": "Nově načíst entity integrace Generic IP camera",
|
"generic": "Nově načíst entity integrace Generic IP camera",
|
||||||
"generic_thermostat": "Nově načíst entity integrace Generic thermostat",
|
"generic_thermostat": "Nově načíst entity integrace Generic thermostat",
|
||||||
"group": "Nově načíst skupiny",
|
"group": "Nově načíst skupiny, skupiny entit a notifikační služby",
|
||||||
"heading": "Konfigurace se načítá",
|
"heading": "Konfigurace se načítá",
|
||||||
"history_stats": "Nově načíst entity integrace History stats",
|
"history_stats": "Nově načíst entity integrace History stats",
|
||||||
"homekit": "Nově načíst entity integrace HomeKit",
|
"homekit": "Nově načíst entity integrace HomeKit",
|
||||||
@ -1923,12 +1946,17 @@
|
|||||||
"input_text": "Nově načíst pomocníky - texty",
|
"input_text": "Nově načíst pomocníky - texty",
|
||||||
"introduction": "Některé části Home Assistant lze nově načíst bez nutnosti restartování. Nové načtení zahodí jejich aktuální konfiguraci a načte novou.",
|
"introduction": "Některé části Home Assistant lze nově načíst bez nutnosti restartování. Nové načtení zahodí jejich aktuální konfiguraci a načte novou.",
|
||||||
"min_max": "Nově načíst entity integrace Min/Max",
|
"min_max": "Nově načíst entity integrace Min/Max",
|
||||||
|
"mqtt": "Nově načíst entity integrace MQTT",
|
||||||
"person": "Nově načíst osoby",
|
"person": "Nově načíst osoby",
|
||||||
"ping": "Nově načíst entity integrace Ping",
|
"ping": "Nově načíst entity integrace Ping",
|
||||||
"rest": "Nově načíst entity integrace Rest",
|
"reload": "Nově načíst integraci {domain}",
|
||||||
|
"rest": "Nově načíst entity a notifikační služby integrace Rest",
|
||||||
|
"rpi_gpio": "Nově načíst entity integrace Raspberry Pi GPIO",
|
||||||
"scene": "Nově načíst scény",
|
"scene": "Nově načíst scény",
|
||||||
"script": "Nově načíst skripty",
|
"script": "Nově načíst skripty",
|
||||||
|
"smtp": "Nově načíst notifikační služby integrace SMTP",
|
||||||
"statistics": "Nově načíst entity integrace Statistics",
|
"statistics": "Nově načíst entity integrace Statistics",
|
||||||
|
"telegram": "Nově načíst notifikační služby integrace Telegram",
|
||||||
"template": "Nově načíst entity integrace Template",
|
"template": "Nově načíst entity integrace Template",
|
||||||
"trend": "Nově načíst entity integrace Trend",
|
"trend": "Nově načíst entity integrace Trend",
|
||||||
"universal": "Nově načíst entity integrace Universal media player",
|
"universal": "Nově načíst entity integrace Universal media player",
|
||||||
@ -2017,7 +2045,7 @@
|
|||||||
"system": "Systémový"
|
"system": "Systémový"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users_privileges_note": "Skupina uživatelů je v přípravě. Uživatel nebude moci spravovat instanci prostřednictvím uživatelského rozhraní. Stále kontrolujeme všechny koncové body API pro správu, abychom zajistili, že správně omezují přístup."
|
"users_privileges_note": "Skupiny uživatelů jsou v přípravě. Uživatel je nebude moci spravovat prostřednictvím uživatelského rozhraní. Stále kontrolujeme API pro správu, abychom zajistili, že správně omezuje přístup pouze pro administrátory."
|
||||||
},
|
},
|
||||||
"zha": {
|
"zha": {
|
||||||
"add_device_page": {
|
"add_device_page": {
|
||||||
@ -2549,7 +2577,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "Podle karty",
|
||||||
|
"by_entity": "Podle entity",
|
||||||
"custom_card": "Vlastní",
|
"custom_card": "Vlastní",
|
||||||
|
"domain": "Doména",
|
||||||
|
"entity": "Entita",
|
||||||
"no_description": "Žádný popis není k dispozici."
|
"no_description": "Žádný popis není k dispozici."
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2563,6 +2595,7 @@
|
|||||||
"options": "Více možností",
|
"options": "Více možností",
|
||||||
"pick_card": "Kterou kartu chcete přidat?",
|
"pick_card": "Kterou kartu chcete přidat?",
|
||||||
"pick_card_view_title": "Kterou kartu byste chtěli přidat do svého {name} pohledu?",
|
"pick_card_view_title": "Kterou kartu byste chtěli přidat do svého {name} pohledu?",
|
||||||
|
"search_cards": "Vyhledat karty",
|
||||||
"show_code_editor": "Zobrazit editor kódu",
|
"show_code_editor": "Zobrazit editor kódu",
|
||||||
"show_visual_editor": "Zobrazit vizuální editor",
|
"show_visual_editor": "Zobrazit vizuální editor",
|
||||||
"toggle_editor": "Přepnout Editor",
|
"toggle_editor": "Přepnout Editor",
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
"logbook": "Logbook",
|
"logbook": "Logbook",
|
||||||
"mailbox": "Mailbox",
|
"mailbox": "Mailbox",
|
||||||
"map": "Map",
|
"map": "Map",
|
||||||
|
"media_browser": "Media Browser",
|
||||||
"profile": "Profile",
|
"profile": "Profile",
|
||||||
"shopping_list": "Shopping list",
|
"shopping_list": "Shopping list",
|
||||||
"states": "Overview"
|
"states": "Overview"
|
||||||
@ -563,6 +564,8 @@
|
|||||||
"no_history_found": "No state history found."
|
"no_history_found": "No state history found."
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "Your browser does not support the audio element.",
|
||||||
|
"choose_player": "Choose Player",
|
||||||
"choose-source": "Choose Source",
|
"choose-source": "Choose Source",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "Album",
|
"album": "Album",
|
||||||
@ -571,12 +574,17 @@
|
|||||||
"playlist": "Playlist",
|
"playlist": "Playlist",
|
||||||
"server": "Server"
|
"server": "Server"
|
||||||
},
|
},
|
||||||
|
"media_browsing_error": "Media Browsing Error",
|
||||||
|
"media_not_supported": "The Browser Media Player does not support this type of media",
|
||||||
|
"media_player": "Media Player",
|
||||||
"media-player-browser": "Media Player Browser",
|
"media-player-browser": "Media Player Browser",
|
||||||
"no_items": "No items",
|
"no_items": "No items",
|
||||||
"pick": "Pick",
|
"pick": "Pick",
|
||||||
"pick-media": "Pick Media",
|
"pick-media": "Pick Media",
|
||||||
"play": "Play",
|
"play": "Play",
|
||||||
"play-media": "Play Media"
|
"play-media": "Play Media",
|
||||||
|
"video_not_supported": "Your browser does not support the video element.",
|
||||||
|
"web-browser": "Web Browser"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Picture",
|
"label": "Picture",
|
||||||
@ -634,7 +642,7 @@
|
|||||||
"icon": "Icon Override",
|
"icon": "Icon Override",
|
||||||
"icon_error": "Icons should be in the format 'prefix:iconname', e.g. 'mdi:home'",
|
"icon_error": "Icons should be in the format 'prefix:iconname', e.g. 'mdi:home'",
|
||||||
"name": "Name Override",
|
"name": "Name Override",
|
||||||
"note": "Note: this might not work yet with all integrations.",
|
"note": "Note: This might not work yet with all integrations.",
|
||||||
"unavailable": "This entity is not currently available.",
|
"unavailable": "This entity is not currently available.",
|
||||||
"update": "Update"
|
"update": "Update"
|
||||||
},
|
},
|
||||||
@ -1546,6 +1554,7 @@
|
|||||||
"reload_restart_confirm": "Restart Home Assistant to finish reloading this integration",
|
"reload_restart_confirm": "Restart Home Assistant to finish reloading this integration",
|
||||||
"rename": "Rename",
|
"rename": "Rename",
|
||||||
"restart_confirm": "Restart Home Assistant to finish removing this integration",
|
"restart_confirm": "Restart Home Assistant to finish removing this integration",
|
||||||
|
"services": "{count} {count, plural,\n one {service}\n other {services}\n}",
|
||||||
"settings_button": "Edit settings for {integration}",
|
"settings_button": "Edit settings for {integration}",
|
||||||
"system_options": "System options",
|
"system_options": "System options",
|
||||||
"system_options_button": "System options for {integration}",
|
"system_options_button": "System options for {integration}",
|
||||||
@ -1765,8 +1774,21 @@
|
|||||||
"versions": "Obtaining information about firmware and command class versions",
|
"versions": "Obtaining information about firmware and command class versions",
|
||||||
"wakeup": "Setting up support for wakeup queues and messages"
|
"wakeup": "Setting up support for wakeup queues and messages"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "Node Details",
|
||||||
|
"not_found": "Node not found"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "Failed",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "Manufacturer",
|
||||||
|
"model": "Model",
|
||||||
|
"query_stage": "Query Stage",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "If the node is battery powered, be sure to wake it before proceeding",
|
"battery_note": "If the node is battery powered, be sure to wake it before proceeding",
|
||||||
|
"button": "Refresh Node",
|
||||||
"complete": "Node Refresh Complete",
|
"complete": "Node Refresh Complete",
|
||||||
"description": "This will tell OpenZWave to re-interview a node and update the node's command classes, capabilities, and values.",
|
"description": "This will tell OpenZWave to re-interview a node and update the node's command classes, capabilities, and values.",
|
||||||
"node_status": "Node Status",
|
"node_status": "Node Status",
|
||||||
@ -2025,7 +2047,7 @@
|
|||||||
"system": "System"
|
"system": "System"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users_privileges_note": "The users group is a work in progress. The user will be unable to administer the instance via the UI. We're still auditing all management API endpoints to ensure that they correctly limit access to administrators."
|
"users_privileges_note": "The user group feature is a work in progress. The user will be unable to administer the instance via the UI. We're still auditing all management API endpoints to ensure that they correctly limit access to administrators."
|
||||||
},
|
},
|
||||||
"zha": {
|
"zha": {
|
||||||
"add_device_page": {
|
"add_device_page": {
|
||||||
@ -2063,7 +2085,7 @@
|
|||||||
"clusters": {
|
"clusters": {
|
||||||
"header": "Clusters",
|
"header": "Clusters",
|
||||||
"help_cluster_dropdown": "Select a cluster to view attributes and commands.",
|
"help_cluster_dropdown": "Select a cluster to view attributes and commands.",
|
||||||
"introduction": "Clusters are the building blocks for Zigbee functionality. They seperate functionality into logical units. There are client and server types and that are comprised of attributes and commands."
|
"introduction": "Clusters are the building blocks for Zigbee functionality. They separate functionality into logical units. There are client and server types and that are comprised of attributes and commands."
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add_devices": "Add Devices",
|
"add_devices": "Add Devices",
|
||||||
@ -2196,7 +2218,7 @@
|
|||||||
"true": "True"
|
"true": "True"
|
||||||
},
|
},
|
||||||
"node_management": {
|
"node_management": {
|
||||||
"add_to_group": "Add To Group",
|
"add_to_group": "Add to Group",
|
||||||
"entities": "Entities of this node",
|
"entities": "Entities of this node",
|
||||||
"entity_info": "Entity Information",
|
"entity_info": "Entity Information",
|
||||||
"exclude_entity": "Exclude this entity from Home Assistant",
|
"exclude_entity": "Exclude this entity from Home Assistant",
|
||||||
@ -2209,11 +2231,11 @@
|
|||||||
"node_to_control": "Node to control",
|
"node_to_control": "Node to control",
|
||||||
"nodes": "Nodes",
|
"nodes": "Nodes",
|
||||||
"nodes_hint": "Select node to view per-node options",
|
"nodes_hint": "Select node to view per-node options",
|
||||||
"nodes_in_group": "Other Nodes in this group:",
|
"nodes_in_group": "Other nodes in this group:",
|
||||||
"pooling_intensity": "Polling intensity",
|
"pooling_intensity": "Polling intensity",
|
||||||
"protection": "Protection",
|
"protection": "Protection",
|
||||||
"remove_broadcast": "Remove Broadcast",
|
"remove_broadcast": "Remove Broadcast",
|
||||||
"remove_from_group": "Remove From Group",
|
"remove_from_group": "Remove from Group",
|
||||||
"set_protection": "Set Protection"
|
"set_protection": "Set Protection"
|
||||||
},
|
},
|
||||||
"ozw_log": {
|
"ozw_log": {
|
||||||
@ -2575,6 +2597,7 @@
|
|||||||
"options": "More options",
|
"options": "More options",
|
||||||
"pick_card": "Which card would you like to add?",
|
"pick_card": "Which card would you like to add?",
|
||||||
"pick_card_view_title": "Which card would you like to add to your {name} view?",
|
"pick_card_view_title": "Which card would you like to add to your {name} view?",
|
||||||
|
"search_cards": "Search cards",
|
||||||
"show_code_editor": "Show Code Editor",
|
"show_code_editor": "Show Code Editor",
|
||||||
"show_visual_editor": "Show Visual Editor",
|
"show_visual_editor": "Show Visual Editor",
|
||||||
"toggle_editor": "Toggle Editor",
|
"toggle_editor": "Toggle Editor",
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
"default": {
|
"default": {
|
||||||
"entity_not_found": "Entité introuvable",
|
"entity_not_found": "Entité introuvable",
|
||||||
"error": "Erreur",
|
"error": "Erreur",
|
||||||
"unavailable": "Indisponible",
|
"unavailable": "Indispo.",
|
||||||
"unknown": "Inconnu"
|
"unknown": "Inconnu"
|
||||||
},
|
},
|
||||||
"device_tracker": {
|
"device_tracker": {
|
||||||
@ -170,7 +170,7 @@
|
|||||||
"on": "Problème"
|
"on": "Problème"
|
||||||
},
|
},
|
||||||
"safety": {
|
"safety": {
|
||||||
"off": "Sécurisé",
|
"off": "Sûr",
|
||||||
"on": "Dangereux"
|
"on": "Dangereux"
|
||||||
},
|
},
|
||||||
"smoke": {
|
"smoke": {
|
||||||
@ -318,7 +318,7 @@
|
|||||||
"fog": "Brouillard",
|
"fog": "Brouillard",
|
||||||
"hail": "Grêle",
|
"hail": "Grêle",
|
||||||
"lightning": "Orage",
|
"lightning": "Orage",
|
||||||
"lightning-rainy": "Orage / Pluie",
|
"lightning-rainy": "Orage / Pluvieux",
|
||||||
"partlycloudy": "Partiellement nuageux",
|
"partlycloudy": "Partiellement nuageux",
|
||||||
"pouring": "Averses",
|
"pouring": "Averses",
|
||||||
"rainy": "Pluvieux",
|
"rainy": "Pluvieux",
|
||||||
@ -351,7 +351,7 @@
|
|||||||
"alarm_control_panel": {
|
"alarm_control_panel": {
|
||||||
"arm_away": "Armer (absent)",
|
"arm_away": "Armer (absent)",
|
||||||
"arm_custom_bypass": "Bypass personnalisé",
|
"arm_custom_bypass": "Bypass personnalisé",
|
||||||
"arm_home": "Armer (domicile)",
|
"arm_home": "Armer (présent)",
|
||||||
"arm_night": "Armer nuit",
|
"arm_night": "Armer nuit",
|
||||||
"clear_code": "Effacer",
|
"clear_code": "Effacer",
|
||||||
"code": "Code",
|
"code": "Code",
|
||||||
@ -505,6 +505,7 @@
|
|||||||
"back": "Retour",
|
"back": "Retour",
|
||||||
"cancel": "Annuler",
|
"cancel": "Annuler",
|
||||||
"close": "Fermer",
|
"close": "Fermer",
|
||||||
|
"continue": "Continuer",
|
||||||
"delete": "Supprimer",
|
"delete": "Supprimer",
|
||||||
"error_required": "Obligatoire",
|
"error_required": "Obligatoire",
|
||||||
"loading": "Chargement",
|
"loading": "Chargement",
|
||||||
@ -562,6 +563,8 @@
|
|||||||
"no_history_found": "Aucun historique des valeurs trouvé."
|
"no_history_found": "Aucun historique des valeurs trouvé."
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "Votre navigateur ne prend pas en charge l'élément audio.",
|
||||||
|
"choose_player": "Choisissez le lecteur",
|
||||||
"choose-source": "Choisissez la source",
|
"choose-source": "Choisissez la source",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "Album",
|
"album": "Album",
|
||||||
@ -570,12 +573,16 @@
|
|||||||
"playlist": "Liste de lecture",
|
"playlist": "Liste de lecture",
|
||||||
"server": "Serveur"
|
"server": "Serveur"
|
||||||
},
|
},
|
||||||
|
"media_not_supported": "Le Browser Media Player ne prend pas en charge ce type de média",
|
||||||
|
"media_player": "Lecteur multimédia",
|
||||||
"media-player-browser": "Lecteur multimédia",
|
"media-player-browser": "Lecteur multimédia",
|
||||||
"no_items": "Aucun éléments",
|
"no_items": "Aucun éléments",
|
||||||
"pick": "Choisir",
|
"pick": "Choisir",
|
||||||
"pick-media": "Choisissez un média",
|
"pick-media": "Choisissez un média",
|
||||||
"play": "Lecture",
|
"play": "Lecture",
|
||||||
"play-media": "Lire le média"
|
"play-media": "Lire le média",
|
||||||
|
"video_not_supported": "Votre navigateur ne prend pas en charge l'élément vidéo.",
|
||||||
|
"web-browser": "Navigateur web"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Image",
|
"label": "Image",
|
||||||
@ -689,8 +696,10 @@
|
|||||||
"crop": "Recadrer"
|
"crop": "Recadrer"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "Contrôles",
|
||||||
"dismiss": "Fermer la fenêtre de dialogue",
|
"dismiss": "Fermer la fenêtre de dialogue",
|
||||||
"edit": "Modifier l'entité",
|
"edit": "Modifier l'entité",
|
||||||
|
"history": "Historique",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Créer une zone à partir de l'emplacement actuel"
|
"create_zone": "Créer une zone à partir de l'emplacement actuel"
|
||||||
},
|
},
|
||||||
@ -1442,7 +1451,7 @@
|
|||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"status": "Statut"
|
"status": "Statut"
|
||||||
},
|
},
|
||||||
"introduction": "Home Assistant tient un registre de chaque entité qu'il a déjà vu au moins une fois et qui peut être identifié de manière unique. Chacune de ces entités se verra attribuer un identifiant qui sera réservé à cette seule entité.",
|
"introduction": "Home Assistant tient un registre de chaque entité qu'il a déjà vu au moins une fois et qui peut être identifiée de manière unique. Chacune de ces entités se verra attribuer un identifiant qui sera réservé à cette seule entité.",
|
||||||
"introduction2": "Utilisé le registre des entités pour remplacer le nom, modifier l'ID de l'entité ou supprimer l'entrée de Home Assistant.",
|
"introduction2": "Utilisé le registre des entités pour remplacer le nom, modifier l'ID de l'entité ou supprimer l'entrée de Home Assistant.",
|
||||||
"remove_selected": {
|
"remove_selected": {
|
||||||
"button": "Supprimer la sélection",
|
"button": "Supprimer la sélection",
|
||||||
@ -1534,7 +1543,7 @@
|
|||||||
"firmware": "Firmware: {version}",
|
"firmware": "Firmware: {version}",
|
||||||
"hub": "Connecté via",
|
"hub": "Connecté via",
|
||||||
"manuf": "par {manufacturer}",
|
"manuf": "par {manufacturer}",
|
||||||
"no_area": "Pas de pièce",
|
"no_area": "Pas de zone",
|
||||||
"no_device": "Entités sans appareils",
|
"no_device": "Entités sans appareils",
|
||||||
"no_devices": "Cette intégration n'a pas d'appareils.",
|
"no_devices": "Cette intégration n'a pas d'appareils.",
|
||||||
"options": "Options",
|
"options": "Options",
|
||||||
@ -1740,7 +1749,7 @@
|
|||||||
},
|
},
|
||||||
"network": {
|
"network": {
|
||||||
"header": "Gestion du réseau",
|
"header": "Gestion du réseau",
|
||||||
"introduction": "Διαχείρηση λειτουργιών δικτύου",
|
"introduction": "Gérez les fonctions de niveau réseau.",
|
||||||
"node_count": "{count} nœuds"
|
"node_count": "{count} nœuds"
|
||||||
},
|
},
|
||||||
"node_query_stages": {
|
"node_query_stages": {
|
||||||
@ -1762,8 +1771,21 @@
|
|||||||
"versions": "Obtention d'informations sur les versions des microprogrammes et des classes de commande",
|
"versions": "Obtention d'informations sur les versions des microprogrammes et des classes de commande",
|
||||||
"wakeup": "Configuration de la prise en charge des files d'attente et des messages de réveil"
|
"wakeup": "Configuration de la prise en charge des files d'attente et des messages de réveil"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "Détails du nœud",
|
||||||
|
"not_found": "Nœud introuvable"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "Echec",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "Fabricant",
|
||||||
|
"model": "Modèle",
|
||||||
|
"query_stage": "Étape de requête",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "Si le nœud est alimenté par batterie, assurez-vous de l'activer avant de continuer",
|
"battery_note": "Si le nœud est alimenté par batterie, assurez-vous de l'activer avant de continuer",
|
||||||
|
"button": "Actualiser le nœud",
|
||||||
"complete": "Actualisation du nœud terminée",
|
"complete": "Actualisation du nœud terminée",
|
||||||
"description": "Cela indiquera à OpenZWave de réinterroger le nœud et de le mettre à jour (commandes, possibilités et valeurs).",
|
"description": "Cela indiquera à OpenZWave de réinterroger le nœud et de le mettre à jour (commandes, possibilités et valeurs).",
|
||||||
"node_status": "État du nœud",
|
"node_status": "État du nœud",
|
||||||
@ -1912,7 +1934,7 @@
|
|||||||
"filter": "Recharger les entités de filtre",
|
"filter": "Recharger les entités de filtre",
|
||||||
"generic": "Recharger les entités de caméra IP générique",
|
"generic": "Recharger les entités de caméra IP générique",
|
||||||
"generic_thermostat": "Recharger les entités de thermostat générique",
|
"generic_thermostat": "Recharger les entités de thermostat générique",
|
||||||
"group": "Recharger les groupes",
|
"group": "Recharger les groupes, les entités de groupe et notifier les services",
|
||||||
"heading": "Rechargement de la configuration",
|
"heading": "Rechargement de la configuration",
|
||||||
"history_stats": "Recharger les entités des statistiques historiques",
|
"history_stats": "Recharger les entités des statistiques historiques",
|
||||||
"homekit": "Recharger HomeKit",
|
"homekit": "Recharger HomeKit",
|
||||||
@ -1923,12 +1945,17 @@
|
|||||||
"input_text": "Recharger les entrées de texte (input text)",
|
"input_text": "Recharger les entrées de texte (input text)",
|
||||||
"introduction": "Certaines parties de Home Assistant peuvent être rechargées sans nécessiter de redémarrage. Le fait de cliquer sur recharger déchargera leur configuration actuelle et chargera la nouvelle.",
|
"introduction": "Certaines parties de Home Assistant peuvent être rechargées sans nécessiter de redémarrage. Le fait de cliquer sur recharger déchargera leur configuration actuelle et chargera la nouvelle.",
|
||||||
"min_max": "Recharger les entités min/max",
|
"min_max": "Recharger les entités min/max",
|
||||||
|
"mqtt": "Recharger les entités mqtt",
|
||||||
"person": "Recharger les personnes",
|
"person": "Recharger les personnes",
|
||||||
"ping": "Recharger les entités de capteur binaire ping",
|
"ping": "Recharger les entités de capteur binaire ping",
|
||||||
"rest": "Recharger les entités REST",
|
"reload": "Recharger {domain}",
|
||||||
|
"rest": "Recharger les entités REST et notifier les services",
|
||||||
|
"rpi_gpio": "Recharger les entités GPIO du Raspberry Pi",
|
||||||
"scene": "Recharger les scènes",
|
"scene": "Recharger les scènes",
|
||||||
"script": "Recharger les scripts",
|
"script": "Recharger les scripts",
|
||||||
|
"smtp": "Recharger les services de notification smtp",
|
||||||
"statistics": "Recharger les entités de statistiques",
|
"statistics": "Recharger les entités de statistiques",
|
||||||
|
"telegram": "Recharger les services de notification de telegram",
|
||||||
"template": "Recharger les entités modèles",
|
"template": "Recharger les entités modèles",
|
||||||
"trend": "Recharger les entités de tendance",
|
"trend": "Recharger les entités de tendance",
|
||||||
"universal": "Recharger les entités de lecteur média universel",
|
"universal": "Recharger les entités de lecteur média universel",
|
||||||
@ -2017,7 +2044,7 @@
|
|||||||
"system": "Système"
|
"system": "Système"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users_privileges_note": "Le groupe d'utilisateurs est en cours de développement. L'utilisateur ne pourra pas gérer l'instance via l'interface. Nous vérifions les entrées de l'interface de gestion pour assurer que les accès soient limités aux administrateurs."
|
"users_privileges_note": "La fonctionnalité de groupe d'utilisateurs est en cours de développement. L'utilisateur ne pourra pas gérer l'instance via l'interface. Nous vérifions toujours tous les points terminaisons d'API pour assurer que les accès soient limités aux administrateurs."
|
||||||
},
|
},
|
||||||
"zha": {
|
"zha": {
|
||||||
"add_device_page": {
|
"add_device_page": {
|
||||||
@ -2055,7 +2082,7 @@
|
|||||||
"clusters": {
|
"clusters": {
|
||||||
"header": "Clusters",
|
"header": "Clusters",
|
||||||
"help_cluster_dropdown": "Sélectionnez un cluster pour afficher les attributs et les commandes.",
|
"help_cluster_dropdown": "Sélectionnez un cluster pour afficher les attributs et les commandes.",
|
||||||
"introduction": "Les clusters sont les blocs de construction de la fonctionnalité Zigbee. Ils séparent les fonctionnalités en unités logiques. Il existe des types de clients et de serveurs qui sont composés d'attributs et de commandes."
|
"introduction": "Les grappes sont les éléments de construction de la fonctionnalité Zigbee. Ils séparent les fonctionnalités en unités logiques. Il en existe de types client et serveur et sont composés d'attributs et de commandes."
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add_devices": "Ajouter des appareils",
|
"add_devices": "Ajouter des appareils",
|
||||||
@ -2496,7 +2523,7 @@
|
|||||||
},
|
},
|
||||||
"markdown": {
|
"markdown": {
|
||||||
"content": "Contenu",
|
"content": "Contenu",
|
||||||
"description": "La carte Markdown est utilisée pour afficher du Markdown.",
|
"description": "La carte Markdown est utilisée pour le rendu du Markdown.",
|
||||||
"name": "Markdown"
|
"name": "Markdown"
|
||||||
},
|
},
|
||||||
"media-control": {
|
"media-control": {
|
||||||
@ -2549,7 +2576,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "Par carte",
|
||||||
|
"by_entity": "Par entité",
|
||||||
"custom_card": "Personnalisé",
|
"custom_card": "Personnalisé",
|
||||||
|
"domain": "Domaine",
|
||||||
|
"entity": "Entité",
|
||||||
"no_description": "Aucune description disponible."
|
"no_description": "Aucune description disponible."
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2563,6 +2594,7 @@
|
|||||||
"options": "Plus d'options",
|
"options": "Plus d'options",
|
||||||
"pick_card": "Quelle carte aimeriez-vous ajouter ?",
|
"pick_card": "Quelle carte aimeriez-vous ajouter ?",
|
||||||
"pick_card_view_title": "Quelle carte souhaitez-vous ajouter à votre vue {name} ?",
|
"pick_card_view_title": "Quelle carte souhaitez-vous ajouter à votre vue {name} ?",
|
||||||
|
"search_cards": "Rechercher des cartes",
|
||||||
"show_code_editor": "Afficher l'éditeur de code",
|
"show_code_editor": "Afficher l'éditeur de code",
|
||||||
"show_visual_editor": "Afficher l'éditeur visuel",
|
"show_visual_editor": "Afficher l'éditeur visuel",
|
||||||
"toggle_editor": "Permuter l’éditeur",
|
"toggle_editor": "Permuter l’éditeur",
|
||||||
@ -2765,7 +2797,7 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"code": "Code d'authentification à deux facteurs"
|
"code": "Code d'authentification à deux facteurs"
|
||||||
},
|
},
|
||||||
"description": "Ouvrez le **{mfa_module_name}** sur votre appareil pour afficher votre code d'authentification à deux facteurs et vérifier votre identité:"
|
"description": "Ouvrez le ** {mfa_module_name} ** sur votre appareil pour afficher votre code d'authentification à deux facteurs et confirmer votre identité:"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -2785,7 +2817,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"start_over": "Recommencer",
|
"start_over": "Recommencer",
|
||||||
"unknown_error": "Quelque chose a mal tourné",
|
"unknown_error": "Un problème est survenu",
|
||||||
"working": "Veuillez patienter"
|
"working": "Veuillez patienter"
|
||||||
},
|
},
|
||||||
"initializing": "Initialisation",
|
"initializing": "Initialisation",
|
||||||
|
@ -489,6 +489,7 @@
|
|||||||
"back": "Tilbake",
|
"back": "Tilbake",
|
||||||
"cancel": "Avbryt",
|
"cancel": "Avbryt",
|
||||||
"close": "Lukk",
|
"close": "Lukk",
|
||||||
|
"continue": "Fortsette",
|
||||||
"delete": "Slett",
|
"delete": "Slett",
|
||||||
"error_required": "Nødvendig",
|
"error_required": "Nødvendig",
|
||||||
"loading": "Laster",
|
"loading": "Laster",
|
||||||
@ -672,8 +673,10 @@
|
|||||||
"crop": "Beskjære"
|
"crop": "Beskjære"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "Kontroller",
|
||||||
"dismiss": "Avvis dialogboksen",
|
"dismiss": "Avvis dialogboksen",
|
||||||
"edit": "Redigér entitet",
|
"edit": "Redigér entitet",
|
||||||
|
"history": "Historie",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Opprett sone fra gjeldende plassering"
|
"create_zone": "Opprett sone fra gjeldende plassering"
|
||||||
},
|
},
|
||||||
@ -1866,7 +1869,7 @@
|
|||||||
"filter": "Last inn filter entiteter på nytt",
|
"filter": "Last inn filter entiteter på nytt",
|
||||||
"generic": "Last inn generiske IP-kamera entiteter på nytt",
|
"generic": "Last inn generiske IP-kamera entiteter på nytt",
|
||||||
"generic_thermostat": "Last inn generiske termostat entiteter på nytt",
|
"generic_thermostat": "Last inn generiske termostat entiteter på nytt",
|
||||||
"group": "Last inn grupper på nytt",
|
"group": "Laste inn grupper, gruppere enheter og varsle tjenester på nytt",
|
||||||
"heading": "YAML -Konfigurasjon lastes på nytt",
|
"heading": "YAML -Konfigurasjon lastes på nytt",
|
||||||
"history_stats": "Last inn historiske tilstander på nytt",
|
"history_stats": "Last inn historiske tilstander på nytt",
|
||||||
"homekit": "Last inn HomeKit på nytt",
|
"homekit": "Last inn HomeKit på nytt",
|
||||||
@ -1877,12 +1880,17 @@
|
|||||||
"input_text": "Last inn inndata tekst på nytt",
|
"input_text": "Last inn inndata tekst på nytt",
|
||||||
"introduction": "Noen deler av Home Assistant kan laste inn uten å kreve omstart. Hvis du trykker last på nytt, vil du bytte den nåværende konfigurasjonen med den nye.",
|
"introduction": "Noen deler av Home Assistant kan laste inn uten å kreve omstart. Hvis du trykker last på nytt, vil du bytte den nåværende konfigurasjonen med den nye.",
|
||||||
"min_max": "Last inn min/maks entiteter på nytt",
|
"min_max": "Last inn min/maks entiteter på nytt",
|
||||||
|
"mqtt": "Last inn mqtt-enheter på nytt",
|
||||||
"person": "Last inn personer på nytt",
|
"person": "Last inn personer på nytt",
|
||||||
"ping": "Last inn ping binære sensor entiteter på nytt",
|
"ping": "Last inn ping binære sensor entiteter på nytt",
|
||||||
"rest": "Last inn REST entiteter på nytt",
|
"reload": "Last inn {domain} på nytt",
|
||||||
|
"rest": "Last inn hvileenheter på nytt og varsle tjenester",
|
||||||
|
"rpi_gpio": "Last inn Raspberry Pi GPIO-enheter på nytt",
|
||||||
"scene": "Last inn scener på nytt",
|
"scene": "Last inn scener på nytt",
|
||||||
"script": "Last inn skript på nytt",
|
"script": "Last inn skript på nytt",
|
||||||
|
"smtp": "Last inn smtp-varslingstjenester på nytt",
|
||||||
"statistics": "Last inn statistiske entiteter på nytt",
|
"statistics": "Last inn statistiske entiteter på nytt",
|
||||||
|
"telegram": "Last inn telegram varslingstjenester på nytt",
|
||||||
"template": "Laste inn mal entiteter på nytt",
|
"template": "Laste inn mal entiteter på nytt",
|
||||||
"trend": "Laste inn trend entiteter på nytt",
|
"trend": "Laste inn trend entiteter på nytt",
|
||||||
"universal": "Laste inn universelle mediespiller entiteter på nytt",
|
"universal": "Laste inn universelle mediespiller entiteter på nytt",
|
||||||
@ -2493,7 +2501,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "Med kort",
|
||||||
|
"by_entity": "Etter enhet",
|
||||||
"custom_card": "Tilpasset",
|
"custom_card": "Tilpasset",
|
||||||
|
"domain": "Domene",
|
||||||
|
"entity": "Entitet",
|
||||||
"no_description": "Ingen beskrivelse tilgjengelig."
|
"no_description": "Ingen beskrivelse tilgjengelig."
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
|
@ -505,6 +505,7 @@
|
|||||||
"back": "Wstecz",
|
"back": "Wstecz",
|
||||||
"cancel": "Anuluj",
|
"cancel": "Anuluj",
|
||||||
"close": "Zamknij",
|
"close": "Zamknij",
|
||||||
|
"continue": "Kontynuuj",
|
||||||
"delete": "Usuń",
|
"delete": "Usuń",
|
||||||
"error_required": "To pole jest wymagane",
|
"error_required": "To pole jest wymagane",
|
||||||
"loading": "Ładowanie",
|
"loading": "Ładowanie",
|
||||||
@ -562,6 +563,8 @@
|
|||||||
"no_history_found": "Nie znaleziono historii."
|
"no_history_found": "Nie znaleziono historii."
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "Twoja przeglądarka nie obsługuje elementu audio.",
|
||||||
|
"choose_player": "Wybierz odtwarzacz",
|
||||||
"choose-source": "Wybierz źródło",
|
"choose-source": "Wybierz źródło",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "Album",
|
"album": "Album",
|
||||||
@ -570,12 +573,16 @@
|
|||||||
"playlist": "Lista odtwarzania",
|
"playlist": "Lista odtwarzania",
|
||||||
"server": "Serwer"
|
"server": "Serwer"
|
||||||
},
|
},
|
||||||
|
"media_not_supported": "Przeglądarka odtwarzacza mediów nie obsługuje tego typu mediów",
|
||||||
|
"media_player": "Odtwarzacz mediów",
|
||||||
"media-player-browser": "Przeglądarka odtwarzacza mediów",
|
"media-player-browser": "Przeglądarka odtwarzacza mediów",
|
||||||
"no_items": "Brak elementów",
|
"no_items": "Brak elementów",
|
||||||
"pick": "Wybierz",
|
"pick": "Wybierz",
|
||||||
"pick-media": "Wybierz media",
|
"pick-media": "Wybierz media",
|
||||||
"play": "Odtwarzaj",
|
"play": "Odtwarzaj",
|
||||||
"play-media": "Odtwarzaj media"
|
"play-media": "Odtwarzaj media",
|
||||||
|
"video_not_supported": "Twoja przeglądarka nie obsługuje elementu wideo.",
|
||||||
|
"web-browser": "Przeglądarka internetowa"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Obraz",
|
"label": "Obraz",
|
||||||
@ -689,8 +696,10 @@
|
|||||||
"crop": "Przytnij"
|
"crop": "Przytnij"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "Sterowanie",
|
||||||
"dismiss": "Zamknij okno dialogowe",
|
"dismiss": "Zamknij okno dialogowe",
|
||||||
"edit": "Edytuj encję",
|
"edit": "Edytuj encję",
|
||||||
|
"history": "Historia",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Utwórz strefę z bieżącej lokalizacji"
|
"create_zone": "Utwórz strefę z bieżącej lokalizacji"
|
||||||
},
|
},
|
||||||
@ -1543,6 +1552,7 @@
|
|||||||
"reload_restart_confirm": "Uruchom ponownie Home Assistanta, aby dokończyć ponowne wczytywanie tej integracji",
|
"reload_restart_confirm": "Uruchom ponownie Home Assistanta, aby dokończyć ponowne wczytywanie tej integracji",
|
||||||
"rename": "Zmień nazwę",
|
"rename": "Zmień nazwę",
|
||||||
"restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć usuwanie tej integracji",
|
"restart_confirm": "Zrestartuj Home Assistanta, aby zakończyć usuwanie tej integracji",
|
||||||
|
"services": "{count} {count, plural,\n one {usługa}\n few {usługi}\n many {usług}\n other {usług}\n}",
|
||||||
"settings_button": "Edytuj ustawienia dla {integration}",
|
"settings_button": "Edytuj ustawienia dla {integration}",
|
||||||
"system_options": "Opcje systemowe",
|
"system_options": "Opcje systemowe",
|
||||||
"system_options_button": "Opcje systemowe dla {integration}",
|
"system_options_button": "Opcje systemowe dla {integration}",
|
||||||
@ -1746,7 +1756,7 @@
|
|||||||
"node_query_stages": {
|
"node_query_stages": {
|
||||||
"associations": "Odświeżanie grup skojarzeń i członkostwa",
|
"associations": "Odświeżanie grup skojarzeń i członkostwa",
|
||||||
"cacheload": "Ładowanie informacji z pliku pamięci podręcznej OpenZWave. Węzły baterii pozostaną na tym etapie, dopóki węzeł się nie wybudzi.",
|
"cacheload": "Ładowanie informacji z pliku pamięci podręcznej OpenZWave. Węzły baterii pozostaną na tym etapie, dopóki węzeł się nie wybudzi.",
|
||||||
"complete": "Proces wywiadu jest zakończony",
|
"complete": "Proces odpytywania jest zakończony",
|
||||||
"configuration": "Pobieranie wartości konfiguracyjnych z węzła",
|
"configuration": "Pobieranie wartości konfiguracyjnych z węzła",
|
||||||
"dynamic": "Pobieranie często zmieniających się wartości z węzła",
|
"dynamic": "Pobieranie często zmieniających się wartości z węzła",
|
||||||
"instances": "Pobieranie szczegółowych informacji o instancjach lub kanałach obsługiwanych przez urządzenie",
|
"instances": "Pobieranie szczegółowych informacji o instancjach lub kanałach obsługiwanych przez urządzenie",
|
||||||
@ -1762,8 +1772,21 @@
|
|||||||
"versions": "Pobieranie informacji o wersjach oprogramowania i klas poleceń",
|
"versions": "Pobieranie informacji o wersjach oprogramowania i klas poleceń",
|
||||||
"wakeup": "Konfigurowanie obsługi kolejek wybudzania i wiadomości"
|
"wakeup": "Konfigurowanie obsługi kolejek wybudzania i wiadomości"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "Szczegóły węzła",
|
||||||
|
"not_found": "Nie znaleziono węzła"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "Uszkodzony",
|
||||||
|
"id": "Identyfikator",
|
||||||
|
"manufacturer": "Producent",
|
||||||
|
"model": "Model",
|
||||||
|
"query_stage": "Etap odpytywania",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "Jeśli węzeł jest zasilany bateryjnie, przed kontynuowaniem należy go wybudzić",
|
"battery_note": "Jeśli węzeł jest zasilany bateryjnie, przed kontynuowaniem należy go wybudzić",
|
||||||
|
"button": "Odśwież węzeł",
|
||||||
"complete": "Odświeżanie węzła zakończone",
|
"complete": "Odświeżanie węzła zakończone",
|
||||||
"description": "Poinformuje to OpenZWave o konieczności ponownego odpytania węzła i zaktualizowaniu jego klas poleceń, możliwości i wartości.",
|
"description": "Poinformuje to OpenZWave o konieczności ponownego odpytania węzła i zaktualizowaniu jego klas poleceń, możliwości i wartości.",
|
||||||
"node_status": "Stan węzła",
|
"node_status": "Stan węzła",
|
||||||
@ -1923,12 +1946,17 @@
|
|||||||
"input_text": "Pomocnicy typu tekst",
|
"input_text": "Pomocnicy typu tekst",
|
||||||
"introduction": "Niektóre fragmenty konfiguracji można przeładować bez ponownego uruchamiania. Poniższe przyciski pozwalają na ponowne wczytanie danej części konfiguracji YAML.",
|
"introduction": "Niektóre fragmenty konfiguracji można przeładować bez ponownego uruchamiania. Poniższe przyciski pozwalają na ponowne wczytanie danej części konfiguracji YAML.",
|
||||||
"min_max": "Encje komponentu min/max",
|
"min_max": "Encje komponentu min/max",
|
||||||
|
"mqtt": "Encje komponentu MQTT",
|
||||||
"person": "Osoby",
|
"person": "Osoby",
|
||||||
"ping": "Encje komponentu ping",
|
"ping": "Encje komponentu ping",
|
||||||
|
"reload": "Domenę {domain}",
|
||||||
"rest": "Encje komponentu rest",
|
"rest": "Encje komponentu rest",
|
||||||
|
"rpi_gpio": "Encje komponentu Raspberry Pi GPIO",
|
||||||
"scene": "Sceny",
|
"scene": "Sceny",
|
||||||
"script": "Skrypty",
|
"script": "Skrypty",
|
||||||
|
"smtp": "Usługi powiadomień komponentu SMTP",
|
||||||
"statistics": "Encje komponentu statystyka",
|
"statistics": "Encje komponentu statystyka",
|
||||||
|
"telegram": "Usługi powiadomień komponentu Telegram",
|
||||||
"template": "Szablony encji",
|
"template": "Szablony encji",
|
||||||
"trend": "Encje komponentu trend",
|
"trend": "Encje komponentu trend",
|
||||||
"universal": "Encje komponentu uniwersalny odtwarzacz mediów",
|
"universal": "Encje komponentu uniwersalny odtwarzacz mediów",
|
||||||
@ -2549,7 +2577,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "Według karty",
|
||||||
|
"by_entity": "Według encji",
|
||||||
"custom_card": "Niestandardowa",
|
"custom_card": "Niestandardowa",
|
||||||
|
"domain": "Domena",
|
||||||
|
"entity": "Encja",
|
||||||
"no_description": "Brak dostępnego opisu."
|
"no_description": "Brak dostępnego opisu."
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2563,6 +2595,7 @@
|
|||||||
"options": "Więcej opcji",
|
"options": "Więcej opcji",
|
||||||
"pick_card": "Wybierz kartę, którą chcesz dodać.",
|
"pick_card": "Wybierz kartę, którą chcesz dodać.",
|
||||||
"pick_card_view_title": "Którą kartę chcesz dodać do widoku {name}?",
|
"pick_card_view_title": "Którą kartę chcesz dodać do widoku {name}?",
|
||||||
|
"search_cards": "Szukaj kart",
|
||||||
"show_code_editor": "Edytor kodu",
|
"show_code_editor": "Edytor kodu",
|
||||||
"show_visual_editor": "Edytor wizualny",
|
"show_visual_editor": "Edytor wizualny",
|
||||||
"toggle_editor": "Przełącz edytor",
|
"toggle_editor": "Przełącz edytor",
|
||||||
|
@ -419,7 +419,7 @@
|
|||||||
"unlock": "Desbloquear"
|
"unlock": "Desbloquear"
|
||||||
},
|
},
|
||||||
"media_player": {
|
"media_player": {
|
||||||
"browse_media": "Pesquisar mídia",
|
"browse_media": "Pesquisar media",
|
||||||
"media_next_track": "Próximo",
|
"media_next_track": "Próximo",
|
||||||
"media_play": "Reproduzir",
|
"media_play": "Reproduzir",
|
||||||
"media_play_pause": "Reproduzir/pausar",
|
"media_play_pause": "Reproduzir/pausar",
|
||||||
@ -505,6 +505,7 @@
|
|||||||
"back": "Retroceder",
|
"back": "Retroceder",
|
||||||
"cancel": "Cancelar",
|
"cancel": "Cancelar",
|
||||||
"close": "Fechar",
|
"close": "Fechar",
|
||||||
|
"continue": "Continuar",
|
||||||
"delete": "Apagar",
|
"delete": "Apagar",
|
||||||
"error_required": "Obrigatório",
|
"error_required": "Obrigatório",
|
||||||
"loading": "A carregar",
|
"loading": "A carregar",
|
||||||
@ -562,6 +563,8 @@
|
|||||||
"no_history_found": "Nenhum histórico de estado encontrado."
|
"no_history_found": "Nenhum histórico de estado encontrado."
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "O seu navegador não suporta o elemento de áudio.",
|
||||||
|
"choose_player": "Escolha o Leitor",
|
||||||
"choose-source": "Escolha a fonte",
|
"choose-source": "Escolha a fonte",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "Álbum",
|
"album": "Álbum",
|
||||||
@ -570,12 +573,15 @@
|
|||||||
"playlist": "Lista de reprodução",
|
"playlist": "Lista de reprodução",
|
||||||
"server": "Servidor"
|
"server": "Servidor"
|
||||||
},
|
},
|
||||||
|
"media_player": "Leitor multimédia",
|
||||||
"media-player-browser": "Navegador do Media Player",
|
"media-player-browser": "Navegador do Media Player",
|
||||||
"no_items": "Sem itens",
|
"no_items": "Sem itens",
|
||||||
"pick": "Escolher",
|
"pick": "Escolher",
|
||||||
"pick-media": "Escolha a mídia",
|
"pick-media": "Escolha a média",
|
||||||
"play": "Reproduzir",
|
"play": "Reproduzir",
|
||||||
"play-media": "Reproduzir Mídia"
|
"play-media": "Reproduzir Média",
|
||||||
|
"video_not_supported": "O seu navegador não suporta o elemento de vídeo.",
|
||||||
|
"web-browser": "Navegador web"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Imagem",
|
"label": "Imagem",
|
||||||
@ -600,7 +606,7 @@
|
|||||||
"second": "{count} {count, plural,\n one {segundo}\n other {segundos}\n}",
|
"second": "{count} {count, plural,\n one {segundo}\n other {segundos}\n}",
|
||||||
"week": "{count} {count, plural,\n one {semana}\n other {semanas}\n}"
|
"week": "{count} {count, plural,\n one {semana}\n other {semanas}\n}"
|
||||||
},
|
},
|
||||||
"future": "À {time}",
|
"future": "Há {time}",
|
||||||
"just_now": "Agora mesmo",
|
"just_now": "Agora mesmo",
|
||||||
"never": "Nunca",
|
"never": "Nunca",
|
||||||
"past": "{time} atrás"
|
"past": "{time} atrás"
|
||||||
@ -690,6 +696,7 @@
|
|||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
"dismiss": "Descartar diálogo",
|
"dismiss": "Descartar diálogo",
|
||||||
"edit": "Editar entidade",
|
"edit": "Editar entidade",
|
||||||
|
"history": "Histórico",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Criar zona a partir da localização atual"
|
"create_zone": "Criar zona a partir da localização atual"
|
||||||
},
|
},
|
||||||
@ -851,7 +858,7 @@
|
|||||||
},
|
},
|
||||||
"automation": {
|
"automation": {
|
||||||
"caption": "Automação",
|
"caption": "Automação",
|
||||||
"description": "Criar e editar automações",
|
"description": "Gerir Automações",
|
||||||
"editor": {
|
"editor": {
|
||||||
"actions": {
|
"actions": {
|
||||||
"add": "Adicionar ação",
|
"add": "Adicionar ação",
|
||||||
@ -1357,7 +1364,7 @@
|
|||||||
"caption": "Dispositivos",
|
"caption": "Dispositivos",
|
||||||
"confirm_delete": "Tem a certeza que quer apagar este dispositivo?",
|
"confirm_delete": "Tem a certeza que quer apagar este dispositivo?",
|
||||||
"confirm_rename_entity_ids": "Deseja também renomear os id's de entidade de suas entidades?",
|
"confirm_rename_entity_ids": "Deseja também renomear os id's de entidade de suas entidades?",
|
||||||
"confirm_rename_entity_ids_warning": "Isso não mudará nenhuma configuração (como automações, scripts, cenas, Lovelace) que está usando essas entidades, você mesmo terá que atualizá-las.",
|
"confirm_rename_entity_ids_warning": "Tal não altera nenhuma configuração (como automações, scripts, cenas, Lovelace) que esteja a usar essas entidades, terá que atualizá-las por si.",
|
||||||
"data_table": {
|
"data_table": {
|
||||||
"area": "Área",
|
"area": "Área",
|
||||||
"battery": "Bateria",
|
"battery": "Bateria",
|
||||||
@ -1720,10 +1727,22 @@
|
|||||||
},
|
},
|
||||||
"network": {
|
"network": {
|
||||||
"header": "Gestão de Rede",
|
"header": "Gestão de Rede",
|
||||||
"introduction": "Gerenciar funções em toda a rede.",
|
"introduction": "Gerir funções de rede.",
|
||||||
"node_count": "{count} nós"
|
"node_count": "{count} nós"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "Detalhes do nó",
|
||||||
|
"not_found": "Nó não encontrado"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "Falhou",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "Fabricante",
|
||||||
|
"model": "Modelo",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
|
"button": "Atualizar nó",
|
||||||
"node_status": "Estado do Nó",
|
"node_status": "Estado do Nó",
|
||||||
"refreshing_description": "A atualizar as informações do nó ...",
|
"refreshing_description": "A atualizar as informações do nó ...",
|
||||||
"start_refresh_button": "Iniciar atualização",
|
"start_refresh_button": "Iniciar atualização",
|
||||||
@ -1733,7 +1752,7 @@
|
|||||||
},
|
},
|
||||||
"select_instance": {
|
"select_instance": {
|
||||||
"header": "Selecione uma instância OpenZWave",
|
"header": "Selecione uma instância OpenZWave",
|
||||||
"introduction": "Você tem mais de uma instância OpenZWave em execução. Qual instância você gostaria de gerenciar?"
|
"introduction": "Tem mais do que uma instância Openzwave em execução. Que instância deseja gerir?"
|
||||||
},
|
},
|
||||||
"services": {
|
"services": {
|
||||||
"add_node": "Adicionar nó",
|
"add_node": "Adicionar nó",
|
||||||
@ -1880,9 +1899,11 @@
|
|||||||
"input_text": "Recarregar input texts",
|
"input_text": "Recarregar input texts",
|
||||||
"introduction": "Algumas partes do Home Assistant podem ser recarregadas sem a necessidade de reiniciar. Ao carregar em Recarregar a configuração irá descartar a configuração atual e carregar a nova.",
|
"introduction": "Algumas partes do Home Assistant podem ser recarregadas sem a necessidade de reiniciar. Ao carregar em Recarregar a configuração irá descartar a configuração atual e carregar a nova.",
|
||||||
"min_max": "Recarregar entidades Mín. / Máx.",
|
"min_max": "Recarregar entidades Mín. / Máx.",
|
||||||
|
"mqtt": "Recarregar entidades mqtt",
|
||||||
"person": "Recarregar pessoas",
|
"person": "Recarregar pessoas",
|
||||||
"ping": "Recarregar entidades de sensor binárias de ping",
|
"ping": "Recarregar entidades de sensor binárias de ping",
|
||||||
"rest": "Recarregar entidades REST",
|
"reload": "Recarregar {domain}",
|
||||||
|
"rest": "Recarregar as restantes entidades e notificar serviços",
|
||||||
"scene": "Recarregar cenas",
|
"scene": "Recarregar cenas",
|
||||||
"script": "Recarregar scripts",
|
"script": "Recarregar scripts",
|
||||||
"statistics": "Recarregar entidades estatísticas",
|
"statistics": "Recarregar entidades estatísticas",
|
||||||
@ -2011,7 +2032,7 @@
|
|||||||
"clusters": {
|
"clusters": {
|
||||||
"header": "Clusters",
|
"header": "Clusters",
|
||||||
"help_cluster_dropdown": "Selecione um cluster para visualizar atributos e comandos.",
|
"help_cluster_dropdown": "Selecione um cluster para visualizar atributos e comandos.",
|
||||||
"introduction": "Clusters são os blocos de construção para a funcionalidade Zigbee. Eles separam a funcionalidade em unidades lógicas. Existem tipos de cliente e servidor e que são compostos de atributos e comandos."
|
"introduction": "Os Clusters são os blocos de construção da funcionalidade Zigbee. Eles separam a funcionalidade em unidades lógicas. Existem do tipo cliente e servidor e são compostos de atributos e comandos."
|
||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"add_devices": "Adicionar dispositivos",
|
"add_devices": "Adicionar dispositivos",
|
||||||
@ -2505,7 +2526,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "Pelo Cartão",
|
||||||
|
"by_entity": "Pela Entidade",
|
||||||
"custom_card": "Personalizado",
|
"custom_card": "Personalizado",
|
||||||
|
"domain": "Domínio",
|
||||||
|
"entity": "Entidade",
|
||||||
"no_description": "Não há descrição disponível."
|
"no_description": "Não há descrição disponível."
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2519,6 +2544,7 @@
|
|||||||
"options": "Mais opções",
|
"options": "Mais opções",
|
||||||
"pick_card": "Que cartão gostaria de adicionar?",
|
"pick_card": "Que cartão gostaria de adicionar?",
|
||||||
"pick_card_view_title": "Que cartão você gostaria de adicionar à sua vista {name}?",
|
"pick_card_view_title": "Que cartão você gostaria de adicionar à sua vista {name}?",
|
||||||
|
"search_cards": "Procurar cartões",
|
||||||
"show_code_editor": "Mostrar Editor de Código",
|
"show_code_editor": "Mostrar Editor de Código",
|
||||||
"show_visual_editor": "Mostrar Editor Visual",
|
"show_visual_editor": "Mostrar Editor Visual",
|
||||||
"toggle_editor": "Alternar Editor",
|
"toggle_editor": "Alternar Editor",
|
||||||
@ -2606,7 +2632,7 @@
|
|||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
"close": "Fechar",
|
"close": "Fechar",
|
||||||
"configure_ui": "Configurar UI",
|
"configure_ui": "Configurar Painel",
|
||||||
"exit_edit_mode": "Sair do modo de edição do IU",
|
"exit_edit_mode": "Sair do modo de edição do IU",
|
||||||
"help": "Ajuda",
|
"help": "Ajuda",
|
||||||
"refresh": "Atualizar",
|
"refresh": "Atualizar",
|
||||||
|
@ -505,6 +505,7 @@
|
|||||||
"back": "Назад",
|
"back": "Назад",
|
||||||
"cancel": "Отменить",
|
"cancel": "Отменить",
|
||||||
"close": "Закрыть",
|
"close": "Закрыть",
|
||||||
|
"continue": "Продолжить",
|
||||||
"delete": "Удалить",
|
"delete": "Удалить",
|
||||||
"error_required": "Обязательное поле",
|
"error_required": "Обязательное поле",
|
||||||
"loading": "Загрузка",
|
"loading": "Загрузка",
|
||||||
@ -562,6 +563,7 @@
|
|||||||
"no_history_found": "История не найдена."
|
"no_history_found": "История не найдена."
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"choose_player": "Выберите медиаплеер",
|
||||||
"choose-source": "Выбрать источник",
|
"choose-source": "Выбрать источник",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "Альбом",
|
"album": "Альбом",
|
||||||
@ -570,12 +572,14 @@
|
|||||||
"playlist": "Плейлист",
|
"playlist": "Плейлист",
|
||||||
"server": "Сервер"
|
"server": "Сервер"
|
||||||
},
|
},
|
||||||
|
"media_player": "Медиаплеер",
|
||||||
"media-player-browser": "Браузер медиаплеера",
|
"media-player-browser": "Браузер медиаплеера",
|
||||||
"no_items": "Нет элементов",
|
"no_items": "Нет элементов",
|
||||||
"pick": "Выбрать",
|
"pick": "Выбрать",
|
||||||
"pick-media": "Выбрать Медиа",
|
"pick-media": "Выбрать Медиа",
|
||||||
"play": "Воспроизведение",
|
"play": "Воспроизведение",
|
||||||
"play-media": "Воспроизведение Медиа"
|
"play-media": "Воспроизведение Медиа",
|
||||||
|
"web-browser": "Веб-браузер"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "Изображение",
|
"label": "Изображение",
|
||||||
@ -617,7 +621,7 @@
|
|||||||
"update": "Обновить"
|
"update": "Обновить"
|
||||||
},
|
},
|
||||||
"domain_toggler": {
|
"domain_toggler": {
|
||||||
"reset_entities": "Сбросить объекты",
|
"reset_entities": "Сбросить настройки доступа объектов",
|
||||||
"title": "Переключить домены"
|
"title": "Переключить домены"
|
||||||
},
|
},
|
||||||
"entity_registry": {
|
"entity_registry": {
|
||||||
@ -689,8 +693,10 @@
|
|||||||
"crop": "Обрезать"
|
"crop": "Обрезать"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "Управление",
|
||||||
"dismiss": "Закрыть диалог",
|
"dismiss": "Закрыть диалог",
|
||||||
"edit": "Изменить объект",
|
"edit": "Изменить объект",
|
||||||
|
"history": "История",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Создать зону из текущего местоположения"
|
"create_zone": "Создать зону из текущего местоположения"
|
||||||
},
|
},
|
||||||
@ -1201,15 +1207,19 @@
|
|||||||
},
|
},
|
||||||
"alexa": {
|
"alexa": {
|
||||||
"banner": "Редактирование списка доступных объектов через пользовательский интерфейс отключено, так как Вы уже настроили фильтры в файле configuration.yaml.",
|
"banner": "Редактирование списка доступных объектов через пользовательский интерфейс отключено, так как Вы уже настроили фильтры в файле configuration.yaml.",
|
||||||
|
"dont_expose_entity": "Закрыть доступ",
|
||||||
"expose": "Предоставить доступ",
|
"expose": "Предоставить доступ",
|
||||||
"expose_entity": "Предоставить доступ к объекту",
|
"expose_entity": "Открыть доступ",
|
||||||
"exposed_entities": "Объекты, к которым предоставлен доступ",
|
"exposed": "Всего: {selected}",
|
||||||
|
"exposed_entities": "Объекты, к которым открыт доступ",
|
||||||
|
"follow_domain": "По домену",
|
||||||
"manage_domains": "Управление доменами",
|
"manage_domains": "Управление доменами",
|
||||||
"not_exposed_entities": "Объекты, к которым не предоставлен доступ",
|
"not_exposed": "Всего: {selected}",
|
||||||
|
"not_exposed_entities": "Объекты, к которым закрыт доступ",
|
||||||
"title": "Alexa"
|
"title": "Alexa"
|
||||||
},
|
},
|
||||||
"caption": "Home Assistant Cloud",
|
"caption": "Home Assistant Cloud",
|
||||||
"description_features": "Управление сервером вдали от дома, интеграция с Alexa и Google Assistant",
|
"description_features": "Удалённый доступ к серверу, интеграция с Alexa и Google Assistant",
|
||||||
"description_login": "{email}",
|
"description_login": "{email}",
|
||||||
"description_not_login": "Вход не выполнен",
|
"description_not_login": "Вход не выполнен",
|
||||||
"dialog_certificate": {
|
"dialog_certificate": {
|
||||||
@ -1242,9 +1252,15 @@
|
|||||||
"google": {
|
"google": {
|
||||||
"banner": "Редактирование списка доступных объектов через пользовательский интерфейс отключено, так как Вы уже настроили фильтры в файле configuration.yaml.",
|
"banner": "Редактирование списка доступных объектов через пользовательский интерфейс отключено, так как Вы уже настроили фильтры в файле configuration.yaml.",
|
||||||
"disable_2FA": "Отключить двухфакторную аутентификацию",
|
"disable_2FA": "Отключить двухфакторную аутентификацию",
|
||||||
|
"dont_expose_entity": "Закрыть доступ",
|
||||||
"expose": "Предоставить доступ",
|
"expose": "Предоставить доступ",
|
||||||
"exposed_entities": "Объекты, к которым предоставлен доступ",
|
"expose_entity": "Открыть доступ",
|
||||||
"not_exposed_entities": "Объекты, к которым не предоставлен доступ",
|
"exposed": "Всего: {selected}",
|
||||||
|
"exposed_entities": "Объекты, к которым открыт доступ",
|
||||||
|
"follow_domain": "По домену",
|
||||||
|
"manage_domains": "Управление доменами",
|
||||||
|
"not_exposed": "Всего: {selected}",
|
||||||
|
"not_exposed_entities": "Объекты, к которым закрыт доступ",
|
||||||
"sync_to_google": "Синхронизация изменений с Google.",
|
"sync_to_google": "Синхронизация изменений с Google.",
|
||||||
"title": "Google Assistant"
|
"title": "Google Assistant"
|
||||||
},
|
},
|
||||||
@ -1255,7 +1271,7 @@
|
|||||||
"email": "Адрес электронной почты",
|
"email": "Адрес электронной почты",
|
||||||
"email_error_msg": "Неверный адрес электронной почты.",
|
"email_error_msg": "Неверный адрес электронной почты.",
|
||||||
"forgot_password": "забыли пароль?",
|
"forgot_password": "забыли пароль?",
|
||||||
"introduction": "Home Assistant Cloud обеспечивает безопасный доступ к Вашему серверу, даже если Вы находитесь вдали от дома. Также это даёт возможность подключения к функциям облачных сервисов Amazon Alexa и Google Assistant.",
|
"introduction": "Home Assistant Cloud обеспечивает безопасный доступ к Вашему серверу, даже если Вы находитесь вдали от дома. Также это даёт возможность простого подключения к функциям облачных сервисов Amazon Alexa и Google Assistant.",
|
||||||
"introduction2": "Услуга предоставляется нашим партнером ",
|
"introduction2": "Услуга предоставляется нашим партнером ",
|
||||||
"introduction2a": ", компанией от основателей Home Assistant и Hass.io.",
|
"introduction2a": ", компанией от основателей Home Assistant и Hass.io.",
|
||||||
"introduction3": "Home Assistant Cloud предлагает одноразовый бесплатный пробный период продолжительностью один месяц. Для активации пробного периода платёжная информация не требуется.",
|
"introduction3": "Home Assistant Cloud предлагает одноразовый бесплатный пробный период продолжительностью один месяц. Для активации пробного периода платёжная информация не требуется.",
|
||||||
@ -1402,7 +1418,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": "Сценарии",
|
"scripts": "Сценарии",
|
||||||
"unknown_error": "Неизвестная ошибка.",
|
"unknown_error": "Неизвестная ошибка.",
|
||||||
"unnamed_device": "Безымянное устройство",
|
"unnamed_device": "Устройство без названия",
|
||||||
"update": "Обновить"
|
"update": "Обновить"
|
||||||
},
|
},
|
||||||
"entities": {
|
"entities": {
|
||||||
@ -1533,6 +1549,7 @@
|
|||||||
"reload_restart_confirm": "Перезапустите Home Assistant, чтобы завершить перезагрузку этой интеграции",
|
"reload_restart_confirm": "Перезапустите Home Assistant, чтобы завершить перезагрузку этой интеграции",
|
||||||
"rename": "Переименовать",
|
"rename": "Переименовать",
|
||||||
"restart_confirm": "Перезапустите Home Assistant, чтобы завершить удаление этой интеграции",
|
"restart_confirm": "Перезапустите Home Assistant, чтобы завершить удаление этой интеграции",
|
||||||
|
"services": "{count} {count, plural,\n one {служба}\n other {служб}\n}",
|
||||||
"settings_button": "Настройки интеграции {integration}",
|
"settings_button": "Настройки интеграции {integration}",
|
||||||
"system_options": "Настройки интеграции",
|
"system_options": "Настройки интеграции",
|
||||||
"system_options_button": "Системные параметры интеграции {integration}",
|
"system_options_button": "Системные параметры интеграции {integration}",
|
||||||
@ -1579,7 +1596,7 @@
|
|||||||
"none_found_detail": "Измените критерии поиска",
|
"none_found_detail": "Измените критерии поиска",
|
||||||
"note_about_integrations": "Пока что не все интеграции могут быть настроены через пользовательский интерфейс.",
|
"note_about_integrations": "Пока что не все интеграции могут быть настроены через пользовательский интерфейс.",
|
||||||
"note_about_website_reference": "Все доступные интеграции Вы можете найти на ",
|
"note_about_website_reference": "Все доступные интеграции Вы можете найти на ",
|
||||||
"rename_dialog": "Изменение названия интеграции",
|
"rename_dialog": "Название интеграции",
|
||||||
"rename_input_label": "Название",
|
"rename_input_label": "Название",
|
||||||
"search": "Поиск интеграций"
|
"search": "Поиск интеграций"
|
||||||
},
|
},
|
||||||
@ -1752,8 +1769,21 @@
|
|||||||
"versions": "Получение информации о версиях прошивки и классов команд",
|
"versions": "Получение информации о версиях прошивки и классов команд",
|
||||||
"wakeup": "Настройка поддержки очередей пробуждения и сообщений"
|
"wakeup": "Настройка поддержки очередей пробуждения и сообщений"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "Подробности об узле",
|
||||||
|
"not_found": "Узел не найден"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "Сбой",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "Производитель",
|
||||||
|
"model": "Модель",
|
||||||
|
"query_stage": "Стадия запроса",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "Если узел работает от батареи, обязательно разбудите его, прежде чем продолжить",
|
"battery_note": "Если узел работает от батареи, обязательно разбудите его, прежде чем продолжить",
|
||||||
|
"button": "Обновить узел",
|
||||||
"complete": "Обновление узла завершено",
|
"complete": "Обновление узла завершено",
|
||||||
"description": "Повторный опрос узла и обновление классов команд, возможностей и значений узла.",
|
"description": "Повторный опрос узла и обновление классов команд, возможностей и значений узла.",
|
||||||
"node_status": "Статус узла",
|
"node_status": "Статус узла",
|
||||||
@ -1902,7 +1932,7 @@
|
|||||||
"filter": "Перезагрузить объекты интеграции \"Filter\"",
|
"filter": "Перезагрузить объекты интеграции \"Filter\"",
|
||||||
"generic": "Перезагрузить объекты интеграции \"Generic IP Camera\"",
|
"generic": "Перезагрузить объекты интеграции \"Generic IP Camera\"",
|
||||||
"generic_thermostat": "Перезагрузить объекты интеграции \"Generic Thermostat\"",
|
"generic_thermostat": "Перезагрузить объекты интеграции \"Generic Thermostat\"",
|
||||||
"group": "Перезагрузить группы",
|
"group": "Перезагрузить группы, объекты групп и службы уведомлений",
|
||||||
"heading": "Перезагрузка конфигурации YAML",
|
"heading": "Перезагрузка конфигурации YAML",
|
||||||
"history_stats": "Перезагрузить объекты интеграции \"History Stats\"",
|
"history_stats": "Перезагрузить объекты интеграции \"History Stats\"",
|
||||||
"homekit": "Перезагрузить HomeKit",
|
"homekit": "Перезагрузить HomeKit",
|
||||||
@ -1913,12 +1943,17 @@
|
|||||||
"input_text": "Перезагрузить вспомогательные элементы ввода текста",
|
"input_text": "Перезагрузить вспомогательные элементы ввода текста",
|
||||||
"introduction": "Некоторые компоненты Home Assistant можно перезагрузить без необходимости перезапуска всей системы. Перезагрузка выгружает текущую конфигурацию YAML и загружает новую.",
|
"introduction": "Некоторые компоненты Home Assistant можно перезагрузить без необходимости перезапуска всей системы. Перезагрузка выгружает текущую конфигурацию YAML и загружает новую.",
|
||||||
"min_max": "Перезагрузить объекты интеграции \"Min/Max\"",
|
"min_max": "Перезагрузить объекты интеграции \"Min/Max\"",
|
||||||
|
"mqtt": "Перезагрузить объекты интеграции \"MQTT\"",
|
||||||
"person": "Перезагрузить персоны",
|
"person": "Перезагрузить персоны",
|
||||||
"ping": "Перезагрузить объекты интеграции \"Ping (ICMP)\"",
|
"ping": "Перезагрузить объекты интеграции \"Ping (ICMP)\"",
|
||||||
"rest": "Перезагрузить объекты интеграции \"REST\"",
|
"reload": "Перезагрузить {domain}",
|
||||||
|
"rest": "Перезагрузить объекты и службы уведомлений интеграции \"REST\"",
|
||||||
|
"rpi_gpio": "Перезагрузить объекты интеграции \"Raspberry Pi GPIO\"",
|
||||||
"scene": "Перезагрузить сцены",
|
"scene": "Перезагрузить сцены",
|
||||||
"script": "Перезагрузить сценарии",
|
"script": "Перезагрузить сценарии",
|
||||||
|
"smtp": "Перезагрузить службы уведомлений SMTP",
|
||||||
"statistics": "Перезагрузить объекты интеграции \"Statistics\"",
|
"statistics": "Перезагрузить объекты интеграции \"Statistics\"",
|
||||||
|
"telegram": "Перезагрузить службы уведомлений Telegram",
|
||||||
"template": "Перезагрузить объекты шаблонов",
|
"template": "Перезагрузить объекты шаблонов",
|
||||||
"trend": "Перезагрузить объекты интеграции \"Trend\"",
|
"trend": "Перезагрузить объекты интеграции \"Trend\"",
|
||||||
"universal": "Перезагрузить объекты интеграции \"Universal Media Player\"",
|
"universal": "Перезагрузить объекты интеграции \"Universal Media Player\"",
|
||||||
@ -2007,7 +2042,7 @@
|
|||||||
"system": "Системный"
|
"system": "Системный"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users_privileges_note": "Группа пользователей находится в стадии разработки. В дальнейшем пользователи не смогут администрировать сервер через пользовательский интерфейс. Мы все еще проверяем все конечные точки API управления, чтобы убедиться, что они правильно ограничивают доступ."
|
"users_privileges_note": "Функционал пользователей всё ещё в стадии разработки. В дальнейшем пользователи не смогут администрировать сервер через пользовательский интерфейс. Мы все еще проверяем все конечные точки API управления, чтобы убедиться, что они правильно ограничивают доступ."
|
||||||
},
|
},
|
||||||
"zha": {
|
"zha": {
|
||||||
"add_device_page": {
|
"add_device_page": {
|
||||||
@ -2539,7 +2574,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "Карточки",
|
||||||
|
"by_entity": "Объекты",
|
||||||
"custom_card": "Custom",
|
"custom_card": "Custom",
|
||||||
|
"domain": "Домен",
|
||||||
|
"entity": "Объект",
|
||||||
"no_description": "Описание недоступно."
|
"no_description": "Описание недоступно."
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2553,6 +2592,7 @@
|
|||||||
"options": "Больше параметров",
|
"options": "Больше параметров",
|
||||||
"pick_card": "Какую карточку Вы хотели бы добавить?",
|
"pick_card": "Какую карточку Вы хотели бы добавить?",
|
||||||
"pick_card_view_title": "Какую карточку Вы хотели бы добавить на вкладку {name}?",
|
"pick_card_view_title": "Какую карточку Вы хотели бы добавить на вкладку {name}?",
|
||||||
|
"search_cards": "Поиск карточек",
|
||||||
"show_code_editor": "Текстовый редактор",
|
"show_code_editor": "Текстовый редактор",
|
||||||
"show_visual_editor": "Форма ввода",
|
"show_visual_editor": "Форма ввода",
|
||||||
"toggle_editor": "Переключить редактор",
|
"toggle_editor": "Переключить редактор",
|
||||||
@ -2838,7 +2878,7 @@
|
|||||||
},
|
},
|
||||||
"integration": {
|
"integration": {
|
||||||
"finish": "Готово",
|
"finish": "Готово",
|
||||||
"intro": "Устройства и сервисы представлены в Home Assistant как интеграции. Вы можете добавить их сейчас или сделать это позже в разделе настроек.",
|
"intro": "Устройства и службы представлены в Home Assistant как интеграции. Вы можете добавить их сейчас или сделать это позже в разделе настроек.",
|
||||||
"more_integrations": "Ещё"
|
"more_integrations": "Ещё"
|
||||||
},
|
},
|
||||||
"intro": "Готовы ли Вы разбудить свой дом, вернуть свою конфиденциальность и присоединиться к всемирному сообществу?",
|
"intro": "Готовы ли Вы разбудить свой дом, вернуть свою конфиденциальность и присоединиться к всемирному сообществу?",
|
||||||
|
@ -484,6 +484,7 @@
|
|||||||
"back": "Späť",
|
"back": "Späť",
|
||||||
"cancel": "Zrušiť",
|
"cancel": "Zrušiť",
|
||||||
"close": "Zavrieť",
|
"close": "Zavrieť",
|
||||||
|
"continue": "Pokračovať",
|
||||||
"delete": "Odstrániť",
|
"delete": "Odstrániť",
|
||||||
"loading": "Načítava sa",
|
"loading": "Načítava sa",
|
||||||
"next": "Ďalej",
|
"next": "Ďalej",
|
||||||
@ -533,6 +534,11 @@
|
|||||||
"loading_history": "Načítavam históriu stavov",
|
"loading_history": "Načítavam históriu stavov",
|
||||||
"no_history_found": "Nenašla sa žiadna história stavov"
|
"no_history_found": "Nenašla sa žiadna história stavov"
|
||||||
},
|
},
|
||||||
|
"media-browser": {
|
||||||
|
"choose_player": "Vyberte prehrávač",
|
||||||
|
"media_player": "Prehrávač médií",
|
||||||
|
"web-browser": "Webový prehliadač"
|
||||||
|
},
|
||||||
"related-items": {
|
"related-items": {
|
||||||
"area": "Oblasť",
|
"area": "Oblasť",
|
||||||
"automation": "Súčasťou nasledujúcich automatizácií",
|
"automation": "Súčasťou nasledujúcich automatizácií",
|
||||||
@ -635,6 +641,7 @@
|
|||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
"dismiss": "Zrušiť dialógové okno",
|
"dismiss": "Zrušiť dialógové okno",
|
||||||
"edit": "Upraviť entitu",
|
"edit": "Upraviť entitu",
|
||||||
|
"history": "História",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "Vytvoriť zónu z aktuálnej polohy"
|
"create_zone": "Vytvoriť zónu z aktuálnej polohy"
|
||||||
},
|
},
|
||||||
@ -1534,6 +1541,11 @@
|
|||||||
"title": "MQTT",
|
"title": "MQTT",
|
||||||
"topic": "téma"
|
"topic": "téma"
|
||||||
},
|
},
|
||||||
|
"ozw": {
|
||||||
|
"nodes_table": {
|
||||||
|
"id": "ID"
|
||||||
|
}
|
||||||
|
},
|
||||||
"person": {
|
"person": {
|
||||||
"add_person": "Pridať osobu",
|
"add_person": "Pridať osobu",
|
||||||
"caption": "Osoby",
|
"caption": "Osoby",
|
||||||
@ -1683,6 +1695,8 @@
|
|||||||
"create": "Vytvoriť",
|
"create": "Vytvoriť",
|
||||||
"name": "Meno",
|
"name": "Meno",
|
||||||
"password": "Heslo",
|
"password": "Heslo",
|
||||||
|
"password_confirm": "Potvrdiť heslo",
|
||||||
|
"password_not_match": "Heslá sa nezhodujú",
|
||||||
"username": "Užívateľské meno"
|
"username": "Užívateľské meno"
|
||||||
},
|
},
|
||||||
"caption": "Používatelia",
|
"caption": "Používatelia",
|
||||||
@ -1699,7 +1713,9 @@
|
|||||||
"group": "Skupina",
|
"group": "Skupina",
|
||||||
"id": "ID",
|
"id": "ID",
|
||||||
"name": "Názov",
|
"name": "Názov",
|
||||||
|
"new_password": "Nové heslo",
|
||||||
"owner": "Vlastník",
|
"owner": "Vlastník",
|
||||||
|
"password_changed": "Heslo je zmenené!",
|
||||||
"system_generated": "Systémom vytvorený",
|
"system_generated": "Systémom vytvorený",
|
||||||
"system_generated_users_not_editable": "Nie je možné aktualizovať používateľov generovaných systémom.",
|
"system_generated_users_not_editable": "Nie je možné aktualizovať používateľov generovaných systémom.",
|
||||||
"system_generated_users_not_removable": "Nie je možné odstrániť používateľov generovaných systémom.",
|
"system_generated_users_not_removable": "Nie je možné odstrániť používateľov generovaných systémom.",
|
||||||
@ -1872,6 +1888,10 @@
|
|||||||
"set_wakeup": "Nastaviť interval prebudenia",
|
"set_wakeup": "Nastaviť interval prebudenia",
|
||||||
"true": "True"
|
"true": "True"
|
||||||
},
|
},
|
||||||
|
"node_management": {
|
||||||
|
"add_to_group": "Pridať do skupiny",
|
||||||
|
"remove_from_group": "Odstrániť zo skupiny"
|
||||||
|
},
|
||||||
"ozw_log": {
|
"ozw_log": {
|
||||||
"introduction": "Zobraziť denník. 0 je minimum (načíta celý protokol) a 1000 je maximum. Načítanie zobrazí statický protokol a posledný riadok sa automaticky aktualizuje s určeným počtom riadkov protokolu."
|
"introduction": "Zobraziť denník. 0 je minimum (načíta celý protokol) a 1000 je maximum. Načítanie zobrazí statický protokol a posledný riadok sa automaticky aktualizuje s určeným počtom riadkov protokolu."
|
||||||
},
|
},
|
||||||
@ -2176,6 +2196,7 @@
|
|||||||
"options": "Viac možností",
|
"options": "Viac možností",
|
||||||
"pick_card": "Ktorú kartu chcete pridať?",
|
"pick_card": "Ktorú kartu chcete pridať?",
|
||||||
"pick_card_view_title": "Ktorú kartu chcete pridať do svojho zobrazenia {name} ?",
|
"pick_card_view_title": "Ktorú kartu chcete pridať do svojho zobrazenia {name} ?",
|
||||||
|
"search_cards": "Vyhľadať karty",
|
||||||
"show_code_editor": "Zobraziť editor kódu",
|
"show_code_editor": "Zobraziť editor kódu",
|
||||||
"show_visual_editor": "Zobraziť vizuálny editor",
|
"show_visual_editor": "Zobraziť vizuálny editor",
|
||||||
"toggle_editor": "Prepnúť editor"
|
"toggle_editor": "Prepnúť editor"
|
||||||
|
@ -505,6 +505,7 @@
|
|||||||
"back": "返回",
|
"back": "返回",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"close": "关闭",
|
"close": "关闭",
|
||||||
|
"continue": "继续",
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
"error_required": "必填",
|
"error_required": "必填",
|
||||||
"loading": "加载中",
|
"loading": "加载中",
|
||||||
@ -562,6 +563,8 @@
|
|||||||
"no_history_found": "没有找到历史状态。"
|
"no_history_found": "没有找到历史状态。"
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "您的浏览器不支持音频元素。",
|
||||||
|
"choose_player": "选择播放器",
|
||||||
"choose-source": "选择媒体源",
|
"choose-source": "选择媒体源",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "专辑",
|
"album": "专辑",
|
||||||
@ -570,12 +573,16 @@
|
|||||||
"playlist": "播放列表",
|
"playlist": "播放列表",
|
||||||
"server": "服务器"
|
"server": "服务器"
|
||||||
},
|
},
|
||||||
|
"media_not_supported": "浏览器媒体播放器不支持此类型的媒体",
|
||||||
|
"media_player": "媒体播放器",
|
||||||
"media-player-browser": "媒体播放浏览器",
|
"media-player-browser": "媒体播放浏览器",
|
||||||
"no_items": "没有项目",
|
"no_items": "没有项目",
|
||||||
"pick": "选定",
|
"pick": "选定",
|
||||||
"pick-media": "选定媒体",
|
"pick-media": "选定媒体",
|
||||||
"play": "播放",
|
"play": "播放",
|
||||||
"play-media": "播放媒体"
|
"play-media": "播放媒体",
|
||||||
|
"video_not_supported": "您的浏览器不支持视频元素。",
|
||||||
|
"web-browser": "网页浏览器"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "图片",
|
"label": "图片",
|
||||||
@ -689,8 +696,10 @@
|
|||||||
"crop": "剪裁"
|
"crop": "剪裁"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "控制项",
|
||||||
"dismiss": "关闭对话框",
|
"dismiss": "关闭对话框",
|
||||||
"edit": "编辑实体",
|
"edit": "编辑实体",
|
||||||
|
"history": "历史",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "从当前位置创建地点"
|
"create_zone": "从当前位置创建地点"
|
||||||
},
|
},
|
||||||
@ -1762,8 +1771,21 @@
|
|||||||
"versions": "正在获取固件和命令类版本信息",
|
"versions": "正在获取固件和命令类版本信息",
|
||||||
"wakeup": "正在设置对唤醒队列和消息的支持"
|
"wakeup": "正在设置对唤醒队列和消息的支持"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "节点详细信息",
|
||||||
|
"not_found": "节点未找到"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "故障",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "制造商",
|
||||||
|
"model": "型号",
|
||||||
|
"query_stage": "查询阶段",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "如果节点由电池供电,请确保在继续操作之前将其唤醒",
|
"battery_note": "如果节点由电池供电,请确保在继续操作之前将其唤醒",
|
||||||
|
"button": "刷新节点",
|
||||||
"complete": "节点刷新完成",
|
"complete": "节点刷新完成",
|
||||||
"description": "这将通知 OpenZWave 重新访问节点并更新节点的命令类、功能和值。",
|
"description": "这将通知 OpenZWave 重新访问节点并更新节点的命令类、功能和值。",
|
||||||
"node_status": "节点状态",
|
"node_status": "节点状态",
|
||||||
@ -1912,7 +1934,7 @@
|
|||||||
"filter": "重载 filter 实体",
|
"filter": "重载 filter 实体",
|
||||||
"generic": "重载通用 IP 摄像机实体",
|
"generic": "重载通用 IP 摄像机实体",
|
||||||
"generic_thermostat": "重载通用恒温器实体",
|
"generic_thermostat": "重载通用恒温器实体",
|
||||||
"group": "重载分组",
|
"group": "重载分组、分组实体及通知服务",
|
||||||
"heading": "配置重载",
|
"heading": "配置重载",
|
||||||
"history_stats": "重载历史记录统计实体",
|
"history_stats": "重载历史记录统计实体",
|
||||||
"homekit": "重载 HomeKit",
|
"homekit": "重载 HomeKit",
|
||||||
@ -1923,12 +1945,17 @@
|
|||||||
"input_text": "重载文字输入",
|
"input_text": "重载文字输入",
|
||||||
"introduction": "Home Assistant 中的部分配置可以直接重载,而无需重启服务。点击重载按钮将重新载入新的配置。",
|
"introduction": "Home Assistant 中的部分配置可以直接重载,而无需重启服务。点击重载按钮将重新载入新的配置。",
|
||||||
"min_max": "重载最小值/最大值实体",
|
"min_max": "重载最小值/最大值实体",
|
||||||
|
"mqtt": "重载 mqtt 实体",
|
||||||
"person": "重载人员",
|
"person": "重载人员",
|
||||||
"ping": "重载 ping 二元传感器实体",
|
"ping": "重载 ping 二元传感器实体",
|
||||||
"rest": "重载 REST 实体",
|
"reload": "重载{domain}",
|
||||||
|
"rest": "重载 REST 实体及通知服务",
|
||||||
|
"rpi_gpio": "重载树莓派 GPIO 实体",
|
||||||
"scene": "重载场景",
|
"scene": "重载场景",
|
||||||
"script": "重载脚本",
|
"script": "重载脚本",
|
||||||
|
"smtp": "重载 smtp 通知服务",
|
||||||
"statistics": "重载 statistics 实体",
|
"statistics": "重载 statistics 实体",
|
||||||
|
"telegram": "重载 telegram 通知服务",
|
||||||
"template": "重载模板实体",
|
"template": "重载模板实体",
|
||||||
"trend": "重载 trend 实体",
|
"trend": "重载 trend 实体",
|
||||||
"universal": "重载通用媒体播放器实体",
|
"universal": "重载通用媒体播放器实体",
|
||||||
@ -2549,7 +2576,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "按卡片",
|
||||||
|
"by_entity": "按实体",
|
||||||
"custom_card": "自定义",
|
"custom_card": "自定义",
|
||||||
|
"domain": "域",
|
||||||
|
"entity": "实体",
|
||||||
"no_description": "没有描述。"
|
"no_description": "没有描述。"
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2563,6 +2594,7 @@
|
|||||||
"options": "更多选项",
|
"options": "更多选项",
|
||||||
"pick_card": "请选择要添加的卡片。",
|
"pick_card": "请选择要添加的卡片。",
|
||||||
"pick_card_view_title": "您想将哪张卡片添加到 {name} 视图?",
|
"pick_card_view_title": "您想将哪张卡片添加到 {name} 视图?",
|
||||||
|
"search_cards": "搜索卡片",
|
||||||
"show_code_editor": "显示代码编辑器",
|
"show_code_editor": "显示代码编辑器",
|
||||||
"show_visual_editor": "显示可视化编辑器",
|
"show_visual_editor": "显示可视化编辑器",
|
||||||
"toggle_editor": "切换编辑器",
|
"toggle_editor": "切换编辑器",
|
||||||
|
@ -505,6 +505,7 @@
|
|||||||
"back": "上一步",
|
"back": "上一步",
|
||||||
"cancel": "取消",
|
"cancel": "取消",
|
||||||
"close": "關閉",
|
"close": "關閉",
|
||||||
|
"continue": "繼續",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"error_required": "必填",
|
"error_required": "必填",
|
||||||
"loading": "讀取中",
|
"loading": "讀取中",
|
||||||
@ -562,6 +563,8 @@
|
|||||||
"no_history_found": "找不到狀態歷史。"
|
"no_history_found": "找不到狀態歷史。"
|
||||||
},
|
},
|
||||||
"media-browser": {
|
"media-browser": {
|
||||||
|
"audio_not_supported": "瀏覽器不支援音效元件。",
|
||||||
|
"choose_player": "選擇播放器",
|
||||||
"choose-source": "選擇來源",
|
"choose-source": "選擇來源",
|
||||||
"content-type": {
|
"content-type": {
|
||||||
"album": "專輯",
|
"album": "專輯",
|
||||||
@ -570,12 +573,16 @@
|
|||||||
"playlist": "播放列表",
|
"playlist": "播放列表",
|
||||||
"server": "伺服器"
|
"server": "伺服器"
|
||||||
},
|
},
|
||||||
|
"media_not_supported": "瀏覽器媒體播放器不支援此類型媒體",
|
||||||
|
"media_player": "媒體播放器",
|
||||||
"media-player-browser": "媒體播放器瀏覽器",
|
"media-player-browser": "媒體播放器瀏覽器",
|
||||||
"no_items": "沒有項目",
|
"no_items": "沒有項目",
|
||||||
"pick": "選擇",
|
"pick": "選擇",
|
||||||
"pick-media": "選擇媒體",
|
"pick-media": "選擇媒體",
|
||||||
"play": "播放",
|
"play": "播放",
|
||||||
"play-media": "播放媒體"
|
"play-media": "播放媒體",
|
||||||
|
"video_not_supported": "瀏覽器不支援影片元件。",
|
||||||
|
"web-browser": "網頁瀏覽器"
|
||||||
},
|
},
|
||||||
"picture-upload": {
|
"picture-upload": {
|
||||||
"label": "照片",
|
"label": "照片",
|
||||||
@ -689,8 +696,10 @@
|
|||||||
"crop": "裁切"
|
"crop": "裁切"
|
||||||
},
|
},
|
||||||
"more_info_control": {
|
"more_info_control": {
|
||||||
|
"controls": "控制",
|
||||||
"dismiss": "忽略對話",
|
"dismiss": "忽略對話",
|
||||||
"edit": "編輯實體",
|
"edit": "編輯實體",
|
||||||
|
"history": "歷史",
|
||||||
"person": {
|
"person": {
|
||||||
"create_zone": "使用目前位置新增區域"
|
"create_zone": "使用目前位置新增區域"
|
||||||
},
|
},
|
||||||
@ -1543,6 +1552,7 @@
|
|||||||
"reload_restart_confirm": "重啟 Home Assistant 以為重整合重新載入",
|
"reload_restart_confirm": "重啟 Home Assistant 以為重整合重新載入",
|
||||||
"rename": "重新命名",
|
"rename": "重新命名",
|
||||||
"restart_confirm": "重啟 Home Assistant 以完成此整合移動",
|
"restart_confirm": "重啟 Home Assistant 以完成此整合移動",
|
||||||
|
"services": "{count} {count, plural,\n one {項服務}\n other {項服務}\n}",
|
||||||
"settings_button": "編輯 {integration} 設定",
|
"settings_button": "編輯 {integration} 設定",
|
||||||
"system_options": "系統選項",
|
"system_options": "系統選項",
|
||||||
"system_options_button": "{integration} 系統選項",
|
"system_options_button": "{integration} 系統選項",
|
||||||
@ -1762,8 +1772,21 @@
|
|||||||
"versions": "獲得韌體與命令 Class 版本資訊",
|
"versions": "獲得韌體與命令 Class 版本資訊",
|
||||||
"wakeup": "設定喚醒序列與訊息之支援"
|
"wakeup": "設定喚醒序列與訊息之支援"
|
||||||
},
|
},
|
||||||
|
"node": {
|
||||||
|
"button": "節點詳細資訊",
|
||||||
|
"not_found": "找不到節點"
|
||||||
|
},
|
||||||
|
"nodes_table": {
|
||||||
|
"failed": "失敗",
|
||||||
|
"id": "ID",
|
||||||
|
"manufacturer": "廠牌",
|
||||||
|
"model": "型號",
|
||||||
|
"query_stage": "查詢階段",
|
||||||
|
"zwave_plus": "Z-Wave Plus"
|
||||||
|
},
|
||||||
"refresh_node": {
|
"refresh_node": {
|
||||||
"battery_note": "假如節點為電池供電、請確定先行喚醒以繼續",
|
"battery_note": "假如節點為電池供電、請確定先行喚醒以繼續",
|
||||||
|
"button": "更新節點",
|
||||||
"complete": "節點更新完成",
|
"complete": "節點更新完成",
|
||||||
"description": "將會通知 OpenZWave 重新探訪節點並更新節點命令 Class、相容性與數值。",
|
"description": "將會通知 OpenZWave 重新探訪節點並更新節點命令 Class、相容性與數值。",
|
||||||
"node_status": "節點狀態",
|
"node_status": "節點狀態",
|
||||||
@ -1912,7 +1935,7 @@
|
|||||||
"filter": "重新載入過濾器實體",
|
"filter": "重新載入過濾器實體",
|
||||||
"generic": "重新載入通用 IP 攝影機實體",
|
"generic": "重新載入通用 IP 攝影機實體",
|
||||||
"generic_thermostat": "重新載入通用溫控器實體",
|
"generic_thermostat": "重新載入通用溫控器實體",
|
||||||
"group": "重新載入群組",
|
"group": "重新載入群組、群組實體及通知服務",
|
||||||
"heading": "YAML 設定新載入中",
|
"heading": "YAML 設定新載入中",
|
||||||
"history_stats": "重新載入歷史狀態實體",
|
"history_stats": "重新載入歷史狀態實體",
|
||||||
"homekit": "重新載入 Homekit",
|
"homekit": "重新載入 Homekit",
|
||||||
@ -1923,12 +1946,17 @@
|
|||||||
"input_text": "重新載入輸入文字",
|
"input_text": "重新載入輸入文字",
|
||||||
"introduction": "Home Assistant 中部分設定無須重啟即可重新載入生效。點選重新載入按鈕,即可解除目前 YAML 設定,並重新載入最新設定。",
|
"introduction": "Home Assistant 中部分設定無須重啟即可重新載入生效。點選重新載入按鈕,即可解除目前 YAML 設定,並重新載入最新設定。",
|
||||||
"min_max": "重新載入最低/最高實體",
|
"min_max": "重新載入最低/最高實體",
|
||||||
|
"mqtt": "重新載入 MQTT 實體",
|
||||||
"person": "重新載入人員",
|
"person": "重新載入人員",
|
||||||
"ping": "重新載入 Pung 二進位傳感器實體",
|
"ping": "重新載入 Pung 二進位傳感器實體",
|
||||||
"rest": "重新載入剩餘實體",
|
"reload": "重新載入{domain}",
|
||||||
|
"rest": "重新載入剩餘實體及通知服務",
|
||||||
|
"rpi_gpio": "重新載入 Raspberry Pi GPIO 實體",
|
||||||
"scene": "重新載入場景",
|
"scene": "重新載入場景",
|
||||||
"script": "重新載入腳本",
|
"script": "重新載入腳本",
|
||||||
|
"smtp": "重新載入 SMTP 通知服務",
|
||||||
"statistics": "重新載入統計資訊實體",
|
"statistics": "重新載入統計資訊實體",
|
||||||
|
"telegram": "重新載入 Telegram 通知服務",
|
||||||
"template": "重新載入範例實體",
|
"template": "重新載入範例實體",
|
||||||
"trend": "重新載入趨勢實體",
|
"trend": "重新載入趨勢實體",
|
||||||
"universal": "重新載入通用媒體播放器實體",
|
"universal": "重新載入通用媒體播放器實體",
|
||||||
@ -2017,7 +2045,7 @@
|
|||||||
"system": "系統"
|
"system": "系統"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users_privileges_note": "使用者群組功能進行中。將無法透過 UI 進行使用者管理,仍在檢視所有管理 API Endpoint 以確保能夠正確符合管理員存取需求。"
|
"users_privileges_note": "使用者群組功能仍在開發中。將無法透過 UI 進行使用者管理,仍在檢視所有管理 API Endpoint 以確保能夠正確符合管理員存取需求。"
|
||||||
},
|
},
|
||||||
"zha": {
|
"zha": {
|
||||||
"add_device_page": {
|
"add_device_page": {
|
||||||
@ -2549,7 +2577,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardpicker": {
|
"cardpicker": {
|
||||||
|
"by_card": "以面板",
|
||||||
|
"by_entity": "以實體",
|
||||||
"custom_card": "自訂面板",
|
"custom_card": "自訂面板",
|
||||||
|
"domain": "區域",
|
||||||
|
"entity": "實體",
|
||||||
"no_description": "無描述可使用。"
|
"no_description": "無描述可使用。"
|
||||||
},
|
},
|
||||||
"edit_card": {
|
"edit_card": {
|
||||||
@ -2563,6 +2595,7 @@
|
|||||||
"options": "更多選項",
|
"options": "更多選項",
|
||||||
"pick_card": "選擇所要新增的面板?",
|
"pick_card": "選擇所要新增的面板?",
|
||||||
"pick_card_view_title": "要加入 {name} 視圖的面板?",
|
"pick_card_view_title": "要加入 {name} 視圖的面板?",
|
||||||
|
"search_cards": "搜尋面板",
|
||||||
"show_code_editor": "顯示編碼編輯器",
|
"show_code_editor": "顯示編碼編輯器",
|
||||||
"show_visual_editor": "顯示視覺編輯器",
|
"show_visual_editor": "顯示視覺編輯器",
|
||||||
"toggle_editor": "切換編輯器",
|
"toggle_editor": "切換編輯器",
|
||||||
|
@ -2710,6 +2710,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/sortablejs@^1.10.6":
|
||||||
|
version "1.10.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/sortablejs/-/sortablejs-1.10.6.tgz#98725ae08f1dfe28b8da0fdf302c417f5ff043c0"
|
||||||
|
integrity sha512-QRz8Z+uw2Y4Gwrtxw8hD782zzuxxugdcq8X/FkPsXUa1kfslhGzy13+4HugO9FXNo+jlWVcE6DYmmegniIQ30A==
|
||||||
|
|
||||||
"@types/tern@*":
|
"@types/tern@*":
|
||||||
version "0.23.3"
|
version "0.23.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460"
|
resolved "https://registry.yarnpkg.com/@types/tern/-/tern-0.23.3.tgz#4b54538f04a88c9ff79de1f6f94f575a7f339460"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user