mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-29 20:26:39 +00:00
commit
b1a414c840
@ -34,6 +34,7 @@ module.exports.babelLoaderConfig = ({ latestBuild }) => {
|
||||
},
|
||||
],
|
||||
"@babel/plugin-proposal-optional-chaining",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator",
|
||||
[
|
||||
require("@babel/plugin-proposal-decorators").default,
|
||||
{ decoratorsBeforeExport: true },
|
||||
|
@ -57,7 +57,7 @@ const handler = (done) => (err, stats) => {
|
||||
|
||||
gulp.task("webpack-watch-app", () => {
|
||||
// we are not calling done, so this command will run forever
|
||||
webpack(bothBuilds(createAppConfig, { isProdBuild: false })).watch(
|
||||
webpack(createAppConfig({ isProdBuild: false, latestBuild: true })).watch(
|
||||
{},
|
||||
handler()
|
||||
);
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 20 KiB |
@ -395,7 +395,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
cards: [
|
||||
{
|
||||
entity: "script.air_cleaner_quiet",
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
name: "AC bed",
|
||||
tap_action: {
|
||||
action: "call-service",
|
||||
@ -408,7 +408,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
{
|
||||
entity: "script.air_cleaner_auto",
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
name: "AC bed",
|
||||
tap_action: {
|
||||
action: "call-service",
|
||||
@ -421,7 +421,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
{
|
||||
entity: "script.air_cleaner_turbo",
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
name: "AC bed",
|
||||
tap_action: {
|
||||
action: "call-service",
|
||||
@ -434,7 +434,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
{
|
||||
entity: "script.ac_off",
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
name: "AC",
|
||||
tap_action: {
|
||||
action: "call-service",
|
||||
@ -447,7 +447,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
{
|
||||
entity: "script.ac_on",
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
name: "AC",
|
||||
tap_action: {
|
||||
action: "call-service",
|
||||
@ -658,7 +658,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
action: "call-service",
|
||||
service: "script.goodnight",
|
||||
},
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
icon: "mdi:weather-night",
|
||||
},
|
||||
{
|
||||
@ -670,7 +670,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
service: "scene.turn_on",
|
||||
},
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
icon: "mdi:coffee-outline",
|
||||
},
|
||||
{
|
||||
@ -682,7 +682,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
service: "scene.turn_on",
|
||||
},
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
icon: "mdi:television-classic",
|
||||
},
|
||||
],
|
||||
@ -743,7 +743,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
service: "light.toggle",
|
||||
},
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
icon: "mdi:page-layout-footer",
|
||||
},
|
||||
{
|
||||
@ -755,7 +755,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({
|
||||
},
|
||||
service: "light.toggle",
|
||||
},
|
||||
type: "entity-button",
|
||||
type: "button",
|
||||
icon: "mdi:page-layout-header",
|
||||
},
|
||||
],
|
||||
|
@ -15,14 +15,14 @@ const CONFIGS = [
|
||||
{
|
||||
heading: "Basic example",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
entity: light.bed_light
|
||||
`,
|
||||
},
|
||||
{
|
||||
heading: "With Name",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
name: Bedroom
|
||||
entity: light.bed_light
|
||||
`,
|
||||
@ -30,7 +30,7 @@ const CONFIGS = [
|
||||
{
|
||||
heading: "With Icon",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
entity: light.bed_light
|
||||
icon: mdi:hotel
|
||||
`,
|
||||
@ -38,7 +38,7 @@ const CONFIGS = [
|
||||
{
|
||||
heading: "Without State",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
entity: light.bed_light
|
||||
show_state: false
|
||||
`,
|
||||
@ -46,7 +46,7 @@ const CONFIGS = [
|
||||
{
|
||||
heading: "Custom Tap Action (toggle)",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
entity: light.bed_light
|
||||
tap_action:
|
||||
action: toggle
|
||||
@ -55,7 +55,7 @@ const CONFIGS = [
|
||||
{
|
||||
heading: "Running Service",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
entity: light.bed_light
|
||||
service: light.toggle
|
||||
`,
|
||||
@ -63,13 +63,13 @@ const CONFIGS = [
|
||||
{
|
||||
heading: "Invalid Entity",
|
||||
config: `
|
||||
- type: entity-button
|
||||
- type: button
|
||||
entity: sensor.invalid_entity
|
||||
`,
|
||||
},
|
||||
];
|
||||
|
||||
class DemoEntityButtonEntity extends PolymerElement {
|
||||
class DemoButtonEntity extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<demo-cards
|
||||
@ -97,4 +97,4 @@ class DemoEntityButtonEntity extends PolymerElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("demo-hui-entity-button-card", DemoEntityButtonEntity);
|
||||
customElements.define("demo-hui-button-card", DemoButtonEntity);
|
||||
|
54
package.json
54
package.json
@ -18,15 +18,15 @@
|
||||
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@material/chips": "^3.2.0",
|
||||
"@material/data-table": "^3.2.0",
|
||||
"@material/mwc-base": "^0.10.0",
|
||||
"@material/mwc-button": "^0.10.0",
|
||||
"@material/mwc-checkbox": "^0.10.0",
|
||||
"@material/mwc-dialog": "^0.10.0",
|
||||
"@material/mwc-fab": "^0.10.0",
|
||||
"@material/mwc-ripple": "^0.10.0",
|
||||
"@material/mwc-switch": "^0.10.0",
|
||||
"@material/chips": "^5.0.0",
|
||||
"@material/data-table": "^5.0.0",
|
||||
"@material/mwc-base": "^0.13.0",
|
||||
"@material/mwc-button": "^0.13.0",
|
||||
"@material/mwc-checkbox": "^0.13.0",
|
||||
"@material/mwc-dialog": "^0.13.0",
|
||||
"@material/mwc-fab": "^0.13.0",
|
||||
"@material/mwc-ripple": "^0.13.0",
|
||||
"@material/mwc-switch": "^0.13.0",
|
||||
"@mdi/svg": "4.9.95",
|
||||
"@polymer/app-layout": "^3.0.2",
|
||||
"@polymer/app-localize-behavior": "^3.0.1",
|
||||
@ -70,8 +70,8 @@
|
||||
"@polymer/paper-tooltip": "^3.0.1",
|
||||
"@polymer/polymer": "3.1.0",
|
||||
"@thomasloven/round-slider": "0.3.7",
|
||||
"@vaadin/vaadin-combo-box": "^5.0.6",
|
||||
"@vaadin/vaadin-date-picker": "^4.0.3",
|
||||
"@vaadin/vaadin-combo-box": "^5.0.10",
|
||||
"@vaadin/vaadin-date-picker": "^4.0.7",
|
||||
"@webcomponents/shadycss": "^1.9.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.2.7",
|
||||
"chart.js": "~2.8.0",
|
||||
@ -79,6 +79,7 @@
|
||||
"codemirror": "^5.49.0",
|
||||
"cpx": "^1.5.0",
|
||||
"deep-clone-simple": "^1.1.1",
|
||||
"deep-freeze": "^0.0.1",
|
||||
"es6-object-assign": "^1.1.0",
|
||||
"fecha": "^3.0.2",
|
||||
"fuse.js": "^3.4.4",
|
||||
@ -108,16 +109,17 @@
|
||||
"xss": "^1.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.4",
|
||||
"@babel/plugin-external-helpers": "^7.7.4",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-proposal-decorators": "^7.7.4",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.7.4",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.7.4",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.7.4",
|
||||
"@babel/plugin-transform-react-jsx": "^7.7.4",
|
||||
"@babel/preset-env": "^7.7.4",
|
||||
"@babel/preset-typescript": "^7.7.4",
|
||||
"@babel/core": "^7.8.4",
|
||||
"@babel/plugin-external-helpers": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/plugin-proposal-decorators": "^7.8.3",
|
||||
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.8.3",
|
||||
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@babel/plugin-transform-react-jsx": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.4",
|
||||
"@babel/preset-typescript": "^7.8.3",
|
||||
"@types/chai": "^4.1.7",
|
||||
"@types/chromecast-caf-receiver": "^3.0.12",
|
||||
"@types/chromecast-caf-sender": "^1.0.1",
|
||||
@ -185,7 +187,15 @@
|
||||
"resolutions": {
|
||||
"@webcomponents/webcomponentsjs": "^2.2.10",
|
||||
"@polymer/polymer": "3.1.0",
|
||||
"lit-html": "^1.1.2"
|
||||
"lit-html": "^1.1.2",
|
||||
"@material/button": "^5.0.0",
|
||||
"@material/checkbox": "^5.0.0",
|
||||
"@material/dialog": "^5.0.0",
|
||||
"@material/fab": "^5.0.0",
|
||||
"@material/switch": "^5.0.0",
|
||||
"@material/ripple": "^5.0.0",
|
||||
"@material/dom": "^5.0.0",
|
||||
"@material/touch-target": "^5.0.0"
|
||||
},
|
||||
"main": "src/home-assistant.js",
|
||||
"husky": {
|
||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="home-assistant-frontend",
|
||||
version="20200212.0",
|
||||
version="20200217.0",
|
||||
description="The Home Assistant frontend",
|
||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||
author="The Home Assistant Authors",
|
||||
|
@ -44,6 +44,7 @@ export const DOMAINS_WITH_MORE_INFO = [
|
||||
"light",
|
||||
"lock",
|
||||
"media_player",
|
||||
"person",
|
||||
"script",
|
||||
"sun",
|
||||
"timer",
|
||||
|
@ -7,14 +7,18 @@ import {
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { fireEvent } from "../dom/fire_event";
|
||||
import "@polymer/iron-icon/iron-icon";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import "@material/mwc-button";
|
||||
import "../../components/ha-icon";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
|
||||
@customElement("search-input")
|
||||
class SearchInput extends LitElement {
|
||||
@property() public filter?: string;
|
||||
@property({ type: Boolean, attribute: "no-label-float" })
|
||||
public noLabelFloat? = false;
|
||||
@property({ type: Boolean, attribute: "no-underline" })
|
||||
public noUnderline = false;
|
||||
|
||||
public focus() {
|
||||
this.shadowRoot!.querySelector("paper-input")!.focus();
|
||||
@ -22,18 +26,24 @@ class SearchInput extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<style>
|
||||
.no-underline {
|
||||
--paper-input-container-underline: {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<div class="search-container">
|
||||
<paper-input
|
||||
class=${classMap({ "no-underline": this.noUnderline })}
|
||||
autofocus
|
||||
label="Search"
|
||||
.value=${this.filter}
|
||||
@value-changed=${this._filterInputChanged}
|
||||
.noLabelFloat=${this.noLabelFloat}
|
||||
>
|
||||
<iron-icon
|
||||
icon="hass:magnify"
|
||||
slot="prefix"
|
||||
class="prefix"
|
||||
></iron-icon>
|
||||
<ha-icon icon="hass:magnify" slot="prefix" class="prefix"></ha-icon>
|
||||
${this.filter &&
|
||||
html`
|
||||
<paper-icon-button
|
||||
|
@ -80,6 +80,7 @@ export interface DataTableColumnData extends DataTableSortColumnData {
|
||||
|
||||
export interface DataTableRowData {
|
||||
[key: string]: any;
|
||||
selectable?: boolean;
|
||||
}
|
||||
|
||||
@customElement("ha-data-table")
|
||||
@ -101,6 +102,8 @@ export class HaDataTable extends BaseElement {
|
||||
@property({ type: String }) private _sortColumn?: string;
|
||||
@property({ type: String }) private _sortDirection: SortingDirection = null;
|
||||
@property({ type: Array }) private _filteredData: DataTableRowData[] = [];
|
||||
@query("slot[name='header']") private _header!: HTMLSlotElement;
|
||||
@query(".scroller") private _scroller!: HTMLDivElement;
|
||||
private _sortColumns: {
|
||||
[key: string]: DataTableSortColumnData;
|
||||
} = {};
|
||||
@ -170,7 +173,7 @@ export class HaDataTable extends BaseElement {
|
||||
protected render() {
|
||||
return html`
|
||||
<div class="mdc-data-table">
|
||||
<slot name="header">
|
||||
<slot name="header" @slotchange=${this._calcScrollHeight}>
|
||||
${this._filterable
|
||||
? html`
|
||||
<div class="table-header">
|
||||
@ -181,112 +184,116 @@ export class HaDataTable extends BaseElement {
|
||||
`
|
||||
: ""}
|
||||
</slot>
|
||||
<table class="mdc-data-table__table">
|
||||
<thead>
|
||||
<tr class="mdc-data-table__header-row">
|
||||
${this.selectable
|
||||
? html`
|
||||
<div class="scroller">
|
||||
<table class="mdc-data-table__table">
|
||||
<thead>
|
||||
<tr class="mdc-data-table__header-row">
|
||||
${this.selectable
|
||||
? html`
|
||||
<th
|
||||
class="mdc-data-table__header-cell mdc-data-table__header-cell--checkbox"
|
||||
role="columnheader"
|
||||
scope="col"
|
||||
>
|
||||
<ha-checkbox
|
||||
class="mdc-data-table__row-checkbox"
|
||||
@change=${this._handleHeaderRowCheckboxChange}
|
||||
.indeterminate=${this._headerIndeterminate}
|
||||
.checked=${this._headerChecked}
|
||||
>
|
||||
</ha-checkbox>
|
||||
</th>
|
||||
`
|
||||
: ""}
|
||||
${Object.entries(this.columns).map((columnEntry) => {
|
||||
const [key, column] = columnEntry;
|
||||
const sorted = key === this._sortColumn;
|
||||
const classes = {
|
||||
"mdc-data-table__header-cell--numeric": Boolean(
|
||||
column.type && column.type === "numeric"
|
||||
),
|
||||
"mdc-data-table__header-cell--icon": Boolean(
|
||||
column.type && column.type === "icon"
|
||||
),
|
||||
sortable: Boolean(column.sortable),
|
||||
"not-sorted": Boolean(column.sortable && !sorted),
|
||||
};
|
||||
return html`
|
||||
<th
|
||||
class="mdc-data-table__header-cell mdc-data-table__header-cell--checkbox"
|
||||
class="mdc-data-table__header-cell ${classMap(classes)}"
|
||||
role="columnheader"
|
||||
scope="col"
|
||||
@click=${this._handleHeaderClick}
|
||||
data-column-id="${key}"
|
||||
>
|
||||
<ha-checkbox
|
||||
class="mdc-data-table__row-checkbox"
|
||||
@change=${this._handleHeaderRowCheckboxChange}
|
||||
.indeterminate=${this._headerIndeterminate}
|
||||
.checked=${this._headerChecked}
|
||||
>
|
||||
</ha-checkbox>
|
||||
${column.sortable
|
||||
? html`
|
||||
<ha-icon
|
||||
.icon=${sorted && this._sortDirection === "desc"
|
||||
? "hass:arrow-down"
|
||||
: "hass:arrow-up"}
|
||||
></ha-icon>
|
||||
`
|
||||
: ""}
|
||||
<span>${column.title}</span>
|
||||
</th>
|
||||
`
|
||||
: ""}
|
||||
${Object.entries(this.columns).map((columnEntry) => {
|
||||
const [key, column] = columnEntry;
|
||||
const sorted = key === this._sortColumn;
|
||||
const classes = {
|
||||
"mdc-data-table__header-cell--numeric": Boolean(
|
||||
column.type && column.type === "numeric"
|
||||
),
|
||||
"mdc-data-table__header-cell--icon": Boolean(
|
||||
column.type && column.type === "icon"
|
||||
),
|
||||
sortable: Boolean(column.sortable),
|
||||
"not-sorted": Boolean(column.sortable && !sorted),
|
||||
};
|
||||
return html`
|
||||
<th
|
||||
class="mdc-data-table__header-cell ${classMap(classes)}"
|
||||
role="columnheader"
|
||||
scope="col"
|
||||
@click=${this._handleHeaderClick}
|
||||
data-column-id="${key}"
|
||||
`;
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="mdc-data-table__content">
|
||||
${repeat(
|
||||
this._filteredData!,
|
||||
(row: DataTableRowData) => row[this.id],
|
||||
(row: DataTableRowData) => html`
|
||||
<tr
|
||||
data-row-id="${row[this.id]}"
|
||||
@click=${this._handleRowClick}
|
||||
class="mdc-data-table__row"
|
||||
.selectable=${row.selectable !== false}
|
||||
>
|
||||
${column.sortable
|
||||
${this.selectable
|
||||
? html`
|
||||
<ha-icon
|
||||
.icon=${sorted && this._sortDirection === "desc"
|
||||
? "hass:arrow-down"
|
||||
: "hass:arrow-up"}
|
||||
></ha-icon>
|
||||
<td
|
||||
class="mdc-data-table__cell mdc-data-table__cell--checkbox"
|
||||
>
|
||||
<ha-checkbox
|
||||
class="mdc-data-table__row-checkbox"
|
||||
@change=${this._handleRowCheckboxChange}
|
||||
.disabled=${row.selectable === false}
|
||||
.checked=${this._checkedRows.includes(
|
||||
String(row[this.id])
|
||||
)}
|
||||
>
|
||||
</ha-checkbox>
|
||||
</td>
|
||||
`
|
||||
: ""}
|
||||
<span>${column.title}</span>
|
||||
</th>
|
||||
`;
|
||||
})}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="mdc-data-table__content">
|
||||
${repeat(
|
||||
this._filteredData!,
|
||||
(row: DataTableRowData) => row[this.id],
|
||||
(row: DataTableRowData) => html`
|
||||
<tr
|
||||
data-row-id="${row[this.id]}"
|
||||
@click=${this._handleRowClick}
|
||||
class="mdc-data-table__row"
|
||||
>
|
||||
${this.selectable
|
||||
? html`
|
||||
${Object.entries(this.columns).map((columnEntry) => {
|
||||
const [key, column] = columnEntry;
|
||||
return html`
|
||||
<td
|
||||
class="mdc-data-table__cell mdc-data-table__cell--checkbox"
|
||||
class="mdc-data-table__cell ${classMap({
|
||||
"mdc-data-table__cell--numeric": Boolean(
|
||||
column.type && column.type === "numeric"
|
||||
),
|
||||
"mdc-data-table__cell--icon": Boolean(
|
||||
column.type && column.type === "icon"
|
||||
),
|
||||
})}"
|
||||
>
|
||||
<ha-checkbox
|
||||
class="mdc-data-table__row-checkbox"
|
||||
@change=${this._handleRowCheckboxChange}
|
||||
.checked=${this._checkedRows.includes(
|
||||
String(row[this.id])
|
||||
)}
|
||||
>
|
||||
</ha-checkbox>
|
||||
${column.template
|
||||
? column.template(row[key], row)
|
||||
: row[key]}
|
||||
</td>
|
||||
`
|
||||
: ""}
|
||||
${Object.entries(this.columns).map((columnEntry) => {
|
||||
const [key, column] = columnEntry;
|
||||
return html`
|
||||
<td
|
||||
class="mdc-data-table__cell ${classMap({
|
||||
"mdc-data-table__cell--numeric": Boolean(
|
||||
column.type && column.type === "numeric"
|
||||
),
|
||||
"mdc-data-table__cell--icon": Boolean(
|
||||
column.type && column.type === "icon"
|
||||
),
|
||||
})}"
|
||||
>
|
||||
${column.template
|
||||
? column.template(row[key], row)
|
||||
: row[key]}
|
||||
</td>
|
||||
`;
|
||||
})}
|
||||
</tr>
|
||||
`
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
`;
|
||||
})}
|
||||
</tr>
|
||||
`
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@ -294,9 +301,12 @@ export class HaDataTable extends BaseElement {
|
||||
protected createAdapter(): MDCDataTableAdapter {
|
||||
return {
|
||||
addClassAtRowIndex: (rowIndex: number, cssClasses: string) => {
|
||||
if (!(this.rowElements[rowIndex] as any).selectable) {
|
||||
return;
|
||||
}
|
||||
this.rowElements[rowIndex].classList.add(cssClasses);
|
||||
},
|
||||
getRowCount: () => this.data.length,
|
||||
getRowCount: () => this.rowElements.length,
|
||||
getRowElements: () => this.rowElements,
|
||||
getRowIdAtIndex: (rowIndex: number) => this._getRowIdAtIndex(rowIndex),
|
||||
getRowIndexByChildElement: (el: Element) =>
|
||||
@ -305,7 +315,7 @@ export class HaDataTable extends BaseElement {
|
||||
isCheckboxAtRowIndexChecked: (rowIndex: number) =>
|
||||
this._checkedRows.includes(this._getRowIdAtIndex(rowIndex)),
|
||||
isHeaderRowCheckboxChecked: () => this._headerChecked,
|
||||
isRowsSelectable: () => true,
|
||||
isRowsSelectable: () => this.selectable,
|
||||
notifyRowSelectionChanged: () => undefined,
|
||||
notifySelectedAll: () => undefined,
|
||||
notifyUnselectedAll: () => undefined,
|
||||
@ -328,6 +338,9 @@ export class HaDataTable extends BaseElement {
|
||||
this._headerIndeterminate = indeterminate;
|
||||
},
|
||||
setRowCheckboxCheckedAtIndex: (rowIndex: number, checked: boolean) => {
|
||||
if (!(this.rowElements[rowIndex] as any).selectable) {
|
||||
return;
|
||||
}
|
||||
this._setRowChecked(this._getRowIdAtIndex(rowIndex), checked);
|
||||
},
|
||||
};
|
||||
@ -434,6 +447,11 @@ export class HaDataTable extends BaseElement {
|
||||
this._debounceSearch(ev.detail.value);
|
||||
}
|
||||
|
||||
private async _calcScrollHeight() {
|
||||
await this.updateComplete;
|
||||
this._scroller.style.maxHeight = `calc(100% - ${this._header.clientHeight}px)`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
/* default mdc styles, colors changed, without checkbox styles */
|
||||
@ -507,6 +525,7 @@ export class HaDataTable extends BaseElement {
|
||||
padding-left: 16px;
|
||||
/* @noflip */
|
||||
padding-right: 0;
|
||||
width: 40px;
|
||||
}
|
||||
[dir="rtl"] .mdc-data-table__header-cell--checkbox,
|
||||
.mdc-data-table__header-cell--checkbox[dir="rtl"],
|
||||
@ -549,6 +568,7 @@ export class HaDataTable extends BaseElement {
|
||||
.mdc-data-table__cell--icon {
|
||||
color: var(--secondary-text-color);
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
.mdc-data-table__header-cell {
|
||||
@ -584,8 +604,14 @@ export class HaDataTable extends BaseElement {
|
||||
|
||||
/* custom from here */
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.mdc-data-table {
|
||||
display: block;
|
||||
border-width: var(--data-table-border-width, 1px);
|
||||
height: 100%;
|
||||
}
|
||||
.mdc-data-table__header-cell {
|
||||
overflow: hidden;
|
||||
@ -614,6 +640,16 @@ export class HaDataTable extends BaseElement {
|
||||
.table-header {
|
||||
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
|
||||
}
|
||||
search-input {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
.scroller {
|
||||
overflow: auto;
|
||||
}
|
||||
slot[name="header"] {
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import { fireEvent } from "../../common/dom/fire_event";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
DeviceEntityLookup,
|
||||
} from "../../data/device_registry";
|
||||
import { compare } from "../../common/string/compare";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
@ -30,7 +31,6 @@ import {
|
||||
AreaRegistryEntry,
|
||||
subscribeAreaRegistry,
|
||||
} from "../../data/area_registry";
|
||||
import { DeviceEntityLookup } from "../../panels/config/devices/ha-devices-data-table";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
DeviceRegistryEntry,
|
||||
subscribeDeviceRegistry,
|
||||
computeDeviceName,
|
||||
DeviceEntityLookup,
|
||||
} from "../../data/device_registry";
|
||||
import { compare } from "../../common/string/compare";
|
||||
import { PolymerChangedEvent } from "../../polymer-types";
|
||||
@ -29,7 +30,6 @@ import {
|
||||
AreaRegistryEntry,
|
||||
subscribeAreaRegistry,
|
||||
} from "../../data/area_registry";
|
||||
import { DeviceEntityLookup } from "../../panels/config/devices/ha-devices-data-table";
|
||||
import {
|
||||
EntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
|
@ -10,6 +10,9 @@ import {
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
|
||||
import hassAttributeUtil from "../util/hass-attributes-util";
|
||||
import { until } from "lit-html/directives/until";
|
||||
|
||||
let jsYamlPromise: Promise<typeof import("js-yaml")>;
|
||||
|
||||
@customElement("ha-attributes")
|
||||
class HaAttributes extends LitElement {
|
||||
@ -32,7 +35,7 @@ class HaAttributes extends LitElement {
|
||||
<div class="data-entry">
|
||||
<div class="key">${attribute.replace(/_/g, " ")}</div>
|
||||
<div class="value">
|
||||
${this.formatAttributeValue(attribute)}
|
||||
${this.formatAttribute(attribute)}
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
@ -63,6 +66,10 @@ class HaAttributes extends LitElement {
|
||||
color: var(--secondary-text-color);
|
||||
text-align: right;
|
||||
}
|
||||
pre {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
@ -75,18 +82,31 @@ class HaAttributes extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private formatAttributeValue(attribute: string): string {
|
||||
private formatAttribute(attribute: string): string | TemplateResult {
|
||||
if (!this.stateObj) {
|
||||
return "-";
|
||||
}
|
||||
const value = this.stateObj.attributes[attribute];
|
||||
return this.formatAttributeValue(value);
|
||||
}
|
||||
|
||||
private formatAttributeValue(value: any): string | TemplateResult {
|
||||
if (value === null) {
|
||||
return "-";
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.join(", ");
|
||||
if (
|
||||
(Array.isArray(value) && value.some((val) => val instanceof Object)) ||
|
||||
(!Array.isArray(value) && value instanceof Object)
|
||||
) {
|
||||
if (!jsYamlPromise) {
|
||||
jsYamlPromise = import(/* webpackChunkName: "js-yaml" */ "js-yaml");
|
||||
}
|
||||
const yaml = jsYamlPromise.then((jsYaml) => jsYaml.safeDump(value));
|
||||
return html`
|
||||
<pre>${until(yaml, "")}</pre>
|
||||
`;
|
||||
}
|
||||
return value instanceof Object ? JSON.stringify(value, null, 2) : value;
|
||||
return Array.isArray(value) ? value.join(", ") : value;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ const MwcCheckbox = customElements.get("mwc-checkbox") as Constructor<Checkbox>;
|
||||
|
||||
@customElement("ha-checkbox")
|
||||
export class HaCheckbox extends MwcCheckbox {
|
||||
protected firstUpdated() {
|
||||
public firstUpdated() {
|
||||
super.firstUpdated();
|
||||
this.style.setProperty("--mdc-theme-secondary", "var(--primary-color)");
|
||||
}
|
||||
|
157
src/components/ha-form/ha-form-multi_select.ts
Normal file
157
src/components/ha-form/ha-form-multi_select.ts
Normal file
@ -0,0 +1,157 @@
|
||||
import "@polymer/paper-checkbox/paper-checkbox";
|
||||
import "@polymer/paper-menu-button/paper-menu-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import "@polymer/paper-ripple/paper-ripple";
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
query,
|
||||
TemplateResult,
|
||||
CSSResult,
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import {
|
||||
HaFormElement,
|
||||
HaFormMultiSelectData,
|
||||
HaFormMultiSelectSchema,
|
||||
} from "./ha-form";
|
||||
|
||||
@customElement("ha-form-multi_select")
|
||||
export class HaFormMultiSelect extends LitElement implements HaFormElement {
|
||||
@property() public schema!: HaFormMultiSelectSchema;
|
||||
@property() public data!: HaFormMultiSelectData;
|
||||
@property() public label!: string;
|
||||
@property() public suffix!: string;
|
||||
@property() private _init = false;
|
||||
@query("paper-menu-button") private _input?: HTMLElement;
|
||||
|
||||
public focus(): void {
|
||||
if (this._input) {
|
||||
this._input.focus();
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
const options = Array.isArray(this.schema.options)
|
||||
? this.schema.options
|
||||
: Object.entries(this.schema.options!);
|
||||
|
||||
return html`
|
||||
<paper-menu-button horizontal-align="right" vertical-offset="8">
|
||||
<div class="dropdown-trigger" slot="dropdown-trigger">
|
||||
<paper-ripple></paper-ripple>
|
||||
<paper-input
|
||||
id="input"
|
||||
type="text"
|
||||
readonly
|
||||
value=${this.data
|
||||
.map((value) => this.schema.options![value] || value)
|
||||
.join(", ")}
|
||||
label=${this.label}
|
||||
input-role="button"
|
||||
input-aria-haspopup="listbox"
|
||||
autocomplete="off"
|
||||
>
|
||||
<iron-icon
|
||||
icon="paper-dropdown-menu:arrow-drop-down"
|
||||
suffix
|
||||
slot="suffix"
|
||||
></iron-icon>
|
||||
</paper-input>
|
||||
</div>
|
||||
<paper-listbox
|
||||
multi
|
||||
slot="dropdown-content"
|
||||
attr-for-selected="item-value"
|
||||
.selectedValues=${this.data}
|
||||
@selected-items-changed=${this._valueChanged}
|
||||
@iron-select=${this._onSelect}
|
||||
>
|
||||
${// TS doesn't work with union array types https://github.com/microsoft/TypeScript/issues/36390
|
||||
// @ts-ignore
|
||||
options.map((item: string | [string, string]) => {
|
||||
const value = this._optionValue(item);
|
||||
return html`
|
||||
<paper-icon-item .itemValue=${value}>
|
||||
<paper-checkbox
|
||||
.checked=${this.data.includes(value)}
|
||||
slot="item-icon"
|
||||
></paper-checkbox>
|
||||
${this._optionLabel(item)}
|
||||
</paper-icon-item>
|
||||
`;
|
||||
})}
|
||||
</paper-listbox>
|
||||
</paper-menu-button>
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated() {
|
||||
this.updateComplete.then(() => {
|
||||
const input = (this.shadowRoot?.querySelector("paper-input")
|
||||
?.inputElement as any)?.inputElement;
|
||||
if (input) {
|
||||
input.style.textOverflow = "ellipsis";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _optionValue(item: string | string[]): string {
|
||||
return Array.isArray(item) ? item[0] : item;
|
||||
}
|
||||
|
||||
private _optionLabel(item: string | string[]): string {
|
||||
return Array.isArray(item) ? item[1] || item[0] : item;
|
||||
}
|
||||
|
||||
private _onSelect(ev: Event) {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
if (!ev.detail.value || !this._init) {
|
||||
// ignore first call because that is the init of the component
|
||||
this._init = true;
|
||||
return;
|
||||
}
|
||||
|
||||
fireEvent(
|
||||
this,
|
||||
"value-changed",
|
||||
{
|
||||
value: ev.detail.value.map((element) => element.itemValue),
|
||||
},
|
||||
{ bubbles: false }
|
||||
);
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
paper-menu-button {
|
||||
display: block;
|
||||
padding: 0;
|
||||
--paper-item-icon-width: 34px;
|
||||
}
|
||||
paper-ripple {
|
||||
top: 12px;
|
||||
left: 0px;
|
||||
bottom: 8px;
|
||||
right: 0px;
|
||||
}
|
||||
paper-input {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-form-multi_select": HaFormMultiSelect;
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
query,
|
||||
CSSResult,
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { HaFormElement, HaFormSelectData, HaFormSelectSchema } from "./ha-form";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
@ -36,8 +38,10 @@ export class HaFormSelect extends LitElement implements HaFormElement {
|
||||
.selected=${this.data}
|
||||
@selected-item-changed=${this._valueChanged}
|
||||
>
|
||||
${this.schema.options!.map(
|
||||
(item) => html`
|
||||
${// TS doesn't work with union array types https://github.com/microsoft/TypeScript/issues/36390
|
||||
// @ts-ignore
|
||||
this.schema.options!.map(
|
||||
(item: string | [string, string]) => html`
|
||||
<paper-item .itemValue=${this._optionValue(item)}>
|
||||
${this._optionLabel(item)}
|
||||
</paper-item>
|
||||
@ -48,12 +52,12 @@ export class HaFormSelect extends LitElement implements HaFormElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private _optionValue(item) {
|
||||
private _optionValue(item: string | [string, string]) {
|
||||
return Array.isArray(item) ? item[0] : item;
|
||||
}
|
||||
|
||||
private _optionLabel(item) {
|
||||
return Array.isArray(item) ? item[1] : item;
|
||||
private _optionLabel(item: string | [string, string]) {
|
||||
return Array.isArray(item) ? item[1] || item[0] : item;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
@ -64,6 +68,14 @@ export class HaFormSelect extends LitElement implements HaFormElement {
|
||||
value: ev.detail.value.itemValue,
|
||||
});
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
paper-dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
@ -12,6 +12,7 @@ import "./ha-form-integer";
|
||||
import "./ha-form-float";
|
||||
import "./ha-form-boolean";
|
||||
import "./ha-form-select";
|
||||
import "./ha-form-multi_select";
|
||||
import "./ha-form-positive_time_period_dict";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { dynamicElement } from "../../common/dom/dynamic-element-directive";
|
||||
@ -22,6 +23,7 @@ export type HaFormSchema =
|
||||
| HaFormFloatSchema
|
||||
| HaFormBooleanSchema
|
||||
| HaFormSelectSchema
|
||||
| HaFormMultiSelectSchema
|
||||
| HaFormTimeSchema;
|
||||
|
||||
export interface HaFormBaseSchema {
|
||||
@ -41,7 +43,12 @@ export interface HaFormIntegerSchema extends HaFormBaseSchema {
|
||||
|
||||
export interface HaFormSelectSchema extends HaFormBaseSchema {
|
||||
type: "select";
|
||||
options?: string[];
|
||||
options?: string[] | Array<[string, string]>;
|
||||
}
|
||||
|
||||
export interface HaFormMultiSelectSchema extends HaFormBaseSchema {
|
||||
type: "multi_select";
|
||||
options?: { [key: string]: string } | string[] | Array<[string, string]>;
|
||||
}
|
||||
|
||||
export interface HaFormFloatSchema extends HaFormBaseSchema {
|
||||
@ -71,6 +78,7 @@ export type HaFormData =
|
||||
| HaFormFloatData
|
||||
| HaFormBooleanData
|
||||
| HaFormSelectData
|
||||
| HaFormMultiSelectData
|
||||
| HaFormTimeData;
|
||||
|
||||
export type HaFormStringData = string;
|
||||
@ -78,6 +86,7 @@ export type HaFormIntegerData = number;
|
||||
export type HaFormFloatData = number;
|
||||
export type HaFormBooleanData = boolean;
|
||||
export type HaFormSelectData = string;
|
||||
export type HaFormMultiSelectData = string[];
|
||||
export interface HaFormTimeData {
|
||||
hours?: number;
|
||||
minutes?: number;
|
||||
|
@ -68,6 +68,13 @@ export class HaRelatedItems extends SubscribeMixin(LitElement) {
|
||||
if (!this._related) {
|
||||
return html``;
|
||||
}
|
||||
if (Object.keys(this._related).length === 0) {
|
||||
return html`
|
||||
<p>
|
||||
${this.hass.localize("ui.components.related-items.no_related_found")}
|
||||
</p>
|
||||
`;
|
||||
}
|
||||
return html`
|
||||
${this._related.config_entry && this._entries
|
||||
? this._related.config_entry.map((relatedConfigEntryId) => {
|
||||
|
@ -597,6 +597,7 @@ class HaSidebar extends LitElement {
|
||||
|
||||
paper-icon-item .item-text {
|
||||
display: none;
|
||||
max-width: calc(100% - 56px);
|
||||
}
|
||||
:host([expanded]) paper-icon-item .item-text {
|
||||
display: block;
|
||||
|
@ -41,7 +41,8 @@ export interface MarkerLocation {
|
||||
id: string;
|
||||
icon?: string;
|
||||
radius_color?: string;
|
||||
editable?: boolean;
|
||||
location_editable?: boolean;
|
||||
radius_editable?: boolean;
|
||||
}
|
||||
|
||||
@customElement("ha-locations-editor")
|
||||
@ -208,7 +209,7 @@ export class HaLocationsEditor extends LitElement {
|
||||
}
|
||||
);
|
||||
circle.addTo(this._leafletMap!);
|
||||
if (location.editable) {
|
||||
if (location.radius_editable || location.location_editable) {
|
||||
// @ts-ignore
|
||||
circle.editing.enable();
|
||||
// @ts-ignore
|
||||
@ -230,19 +231,25 @@ export class HaLocationsEditor extends LitElement {
|
||||
// @ts-ignore
|
||||
(ev: MouseEvent) => this._markerClicked(ev)
|
||||
);
|
||||
resizeMarker.addEventListener(
|
||||
"dragend",
|
||||
// @ts-ignore
|
||||
(ev: DragEndEvent) => this._updateRadius(ev)
|
||||
);
|
||||
if (location.radius_editable) {
|
||||
resizeMarker.addEventListener(
|
||||
"dragend",
|
||||
// @ts-ignore
|
||||
(ev: DragEndEvent) => this._updateRadius(ev)
|
||||
);
|
||||
} else {
|
||||
resizeMarker.remove();
|
||||
}
|
||||
this._locationMarkers![location.id] = circle;
|
||||
} else {
|
||||
this._circles[location.id] = circle;
|
||||
}
|
||||
}
|
||||
if (!location.radius || !location.editable) {
|
||||
if (
|
||||
!location.radius ||
|
||||
(!location.radius_editable && !location.location_editable)
|
||||
) {
|
||||
const options: MarkerOptions = {
|
||||
draggable: Boolean(location.editable),
|
||||
title: location.name,
|
||||
};
|
||||
|
||||
|
311
src/components/map/ha-map.ts
Normal file
311
src/components/map/ha-map.ts
Normal file
@ -0,0 +1,311 @@
|
||||
import "@polymer/paper-icon-button/paper-icon-button";
|
||||
import { Circle, Layer, Map, Marker } from "leaflet";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import {
|
||||
LeafletModuleType,
|
||||
setupLeafletMap,
|
||||
} from "../../common/dom/setup-leaflet-map";
|
||||
import { computeStateDomain } from "../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { debounce } from "../../common/util/debounce";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../../panels/map/ha-entity-marker";
|
||||
|
||||
@customElement("ha-map")
|
||||
class HaMap extends LitElement {
|
||||
@property() public hass?: HomeAssistant;
|
||||
|
||||
@property() public entities?: string[];
|
||||
@property() public darkMode = false;
|
||||
@property() public zoom?: number;
|
||||
// tslint:disable-next-line
|
||||
private Leaflet?: LeafletModuleType;
|
||||
private _leafletMap?: Map;
|
||||
// @ts-ignore
|
||||
private _resizeObserver?: ResizeObserver;
|
||||
private _debouncedResizeListener = debounce(
|
||||
() => {
|
||||
if (!this._leafletMap) {
|
||||
return;
|
||||
}
|
||||
this._leafletMap.invalidateSize();
|
||||
},
|
||||
100,
|
||||
false
|
||||
);
|
||||
private _mapItems: Array<Marker | Circle> = [];
|
||||
private _mapZones: Array<Marker | Circle> = [];
|
||||
private _connected = false;
|
||||
|
||||
public connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this._connected = true;
|
||||
if (this.hasUpdated) {
|
||||
this.loadMap();
|
||||
this._attachObserver();
|
||||
}
|
||||
}
|
||||
|
||||
public disconnectedCallback(): void {
|
||||
super.disconnectedCallback();
|
||||
this._connected = false;
|
||||
|
||||
if (this._leafletMap) {
|
||||
this._leafletMap.remove();
|
||||
this._leafletMap = undefined;
|
||||
this.Leaflet = undefined;
|
||||
}
|
||||
|
||||
if (this._resizeObserver) {
|
||||
this._resizeObserver.unobserve(this._mapEl);
|
||||
} else {
|
||||
window.removeEventListener("resize", this._debouncedResizeListener);
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.entities) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<div id="map"></div>
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues): void {
|
||||
super.firstUpdated(changedProps);
|
||||
this.loadMap();
|
||||
|
||||
if (this._connected) {
|
||||
this._attachObserver();
|
||||
}
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
if (changedProps.has("hass")) {
|
||||
this._drawEntities();
|
||||
this._fitMap();
|
||||
}
|
||||
}
|
||||
|
||||
private get _mapEl(): HTMLDivElement {
|
||||
return this.shadowRoot!.getElementById("map") as HTMLDivElement;
|
||||
}
|
||||
|
||||
private async loadMap(): Promise<void> {
|
||||
[this._leafletMap, this.Leaflet] = await setupLeafletMap(
|
||||
this._mapEl,
|
||||
this.darkMode
|
||||
);
|
||||
this._drawEntities();
|
||||
this._leafletMap.invalidateSize();
|
||||
this._fitMap();
|
||||
}
|
||||
|
||||
private _fitMap(): void {
|
||||
if (!this._leafletMap || !this.Leaflet || !this.hass) {
|
||||
return;
|
||||
}
|
||||
if (this._mapItems.length === 0) {
|
||||
this._leafletMap.setView(
|
||||
new this.Leaflet.LatLng(
|
||||
this.hass.config.latitude,
|
||||
this.hass.config.longitude
|
||||
),
|
||||
this.zoom || 14
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const bounds = this.Leaflet.latLngBounds(
|
||||
this._mapItems ? this._mapItems.map((item) => item.getLatLng()) : []
|
||||
);
|
||||
this._leafletMap.fitBounds(bounds.pad(0.5));
|
||||
|
||||
if (this.zoom && this._leafletMap.getZoom() > this.zoom) {
|
||||
this._leafletMap.setZoom(this.zoom);
|
||||
}
|
||||
}
|
||||
|
||||
private _drawEntities(): void {
|
||||
const hass = this.hass;
|
||||
const map = this._leafletMap;
|
||||
const Leaflet = this.Leaflet;
|
||||
if (!hass || !map || !Leaflet) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._mapItems) {
|
||||
this._mapItems.forEach((marker) => marker.remove());
|
||||
}
|
||||
const mapItems: Layer[] = (this._mapItems = []);
|
||||
|
||||
if (this._mapZones) {
|
||||
this._mapZones.forEach((marker) => marker.remove());
|
||||
}
|
||||
const mapZones: Layer[] = (this._mapZones = []);
|
||||
|
||||
const allEntities = this.entities!.concat();
|
||||
|
||||
for (const entity of allEntities) {
|
||||
const entityId = entity;
|
||||
const stateObj = hass.states[entityId];
|
||||
if (!stateObj) {
|
||||
continue;
|
||||
}
|
||||
const title = computeStateName(stateObj);
|
||||
const {
|
||||
latitude,
|
||||
longitude,
|
||||
passive,
|
||||
icon,
|
||||
radius,
|
||||
entity_picture: entityPicture,
|
||||
gps_accuracy: gpsAccuracy,
|
||||
} = stateObj.attributes;
|
||||
|
||||
if (!(latitude && longitude)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (computeStateDomain(stateObj) === "zone") {
|
||||
// DRAW ZONE
|
||||
if (passive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// create icon
|
||||
let iconHTML = "";
|
||||
if (icon) {
|
||||
const el = document.createElement("ha-icon");
|
||||
el.setAttribute("icon", icon);
|
||||
iconHTML = el.outerHTML;
|
||||
} else {
|
||||
const el = document.createElement("span");
|
||||
el.innerHTML = title;
|
||||
iconHTML = el.outerHTML;
|
||||
}
|
||||
|
||||
// create marker with the icon
|
||||
mapZones.push(
|
||||
Leaflet.marker([latitude, longitude], {
|
||||
icon: Leaflet.divIcon({
|
||||
html: iconHTML,
|
||||
iconSize: [24, 24],
|
||||
className: this.darkMode ? "dark" : "light",
|
||||
}),
|
||||
interactive: false,
|
||||
title,
|
||||
})
|
||||
);
|
||||
|
||||
// create circle around it
|
||||
mapZones.push(
|
||||
Leaflet.circle([latitude, longitude], {
|
||||
interactive: false,
|
||||
color: "#FF9800",
|
||||
radius,
|
||||
})
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// DRAW ENTITY
|
||||
// create icon
|
||||
const entityName = title
|
||||
.split(" ")
|
||||
.map((part) => part[0])
|
||||
.join("")
|
||||
.substr(0, 3);
|
||||
|
||||
// create market with the icon
|
||||
mapItems.push(
|
||||
Leaflet.marker([latitude, longitude], {
|
||||
icon: Leaflet.divIcon({
|
||||
// Leaflet clones this element before adding it to the map. This messes up
|
||||
// our Polymer object and we can't pass data through. Thus we hack like this.
|
||||
html: `
|
||||
<ha-entity-marker
|
||||
entity-id="${entityId}"
|
||||
entity-name="${entityName}"
|
||||
entity-picture="${entityPicture || ""}"
|
||||
></ha-entity-marker>
|
||||
`,
|
||||
iconSize: [48, 48],
|
||||
className: "",
|
||||
}),
|
||||
title: computeStateName(stateObj),
|
||||
})
|
||||
);
|
||||
|
||||
// create circle around if entity has accuracy
|
||||
if (gpsAccuracy) {
|
||||
mapItems.push(
|
||||
Leaflet.circle([latitude, longitude], {
|
||||
interactive: false,
|
||||
color: "#0288D1",
|
||||
radius: gpsAccuracy,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this._mapItems.forEach((marker) => map.addLayer(marker));
|
||||
this._mapZones.forEach((marker) => map.addLayer(marker));
|
||||
}
|
||||
|
||||
private _attachObserver(): void {
|
||||
// Observe changes to map size and invalidate to prevent broken rendering
|
||||
// Uses ResizeObserver in Chrome, otherwise window resize event
|
||||
|
||||
// @ts-ignore
|
||||
if (typeof ResizeObserver === "function") {
|
||||
// @ts-ignore
|
||||
this._resizeObserver = new ResizeObserver(() =>
|
||||
this._debouncedResizeListener()
|
||||
);
|
||||
this._resizeObserver.observe(this._mapEl);
|
||||
} else {
|
||||
window.addEventListener("resize", this._debouncedResizeListener);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
height: 300px;
|
||||
}
|
||||
#map {
|
||||
height: 100%;
|
||||
}
|
||||
#map.dark {
|
||||
background: #090909;
|
||||
}
|
||||
|
||||
.dark {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.light {
|
||||
color: #000000;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-map": HaMap;
|
||||
}
|
||||
}
|
@ -173,6 +173,12 @@ export type Condition =
|
||||
| DeviceCondition
|
||||
| LogicalCondition;
|
||||
|
||||
export const triggerAutomation = (hass: HomeAssistant, entityId: string) => {
|
||||
hass.callService("automation", "trigger", {
|
||||
entity_id: entityId,
|
||||
});
|
||||
};
|
||||
|
||||
export const deleteAutomation = (hass: HomeAssistant, id: string) =>
|
||||
hass.callApi("DELETE", `config/automation/config/${id}`);
|
||||
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { HaFormSchema } from "../components/ha-form/ha-form";
|
||||
|
||||
export interface DataEntryFlowProgressedEvent {
|
||||
type: "data_entry_flow_progressed";
|
||||
data: {
|
||||
@ -7,12 +9,6 @@ export interface DataEntryFlowProgressedEvent {
|
||||
};
|
||||
}
|
||||
|
||||
export interface FieldSchema {
|
||||
name: string;
|
||||
default?: any;
|
||||
optional: boolean;
|
||||
}
|
||||
|
||||
export interface DataEntryFlowProgress {
|
||||
flow_id: string;
|
||||
handler: string;
|
||||
@ -27,7 +23,7 @@ export interface DataEntryFlowStepForm {
|
||||
flow_id: string;
|
||||
handler: string;
|
||||
step_id: string;
|
||||
data_schema: FieldSchema[];
|
||||
data_schema: HaFormSchema[];
|
||||
errors: { [key: string]: string };
|
||||
description_placeholders: { [key: string]: string };
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ export const deviceAutomationsEqual = (
|
||||
export const localizeDeviceAutomationAction = (
|
||||
hass: HomeAssistant,
|
||||
action: DeviceAction
|
||||
) => {
|
||||
): string => {
|
||||
const state = action.entity_id ? hass.states[action.entity_id] : undefined;
|
||||
return (
|
||||
hass.localize(
|
||||
@ -107,17 +107,19 @@ export const localizeDeviceAutomationAction = (
|
||||
"entity_name",
|
||||
state ? computeStateName(state) : action.entity_id || "<unknown>",
|
||||
"subtype",
|
||||
hass.localize(
|
||||
`component.${action.domain}.device_automation.action_subtype.${action.subtype}`
|
||||
) || action.subtype
|
||||
) || `"${action.subtype}" ${action.type}`
|
||||
action.subtype
|
||||
? hass.localize(
|
||||
`component.${action.domain}.device_automation.action_subtype.${action.subtype}`
|
||||
) || action.subtype
|
||||
: ""
|
||||
) || (action.subtype ? `"${action.subtype}" ${action.type}` : action.type!)
|
||||
);
|
||||
};
|
||||
|
||||
export const localizeDeviceAutomationCondition = (
|
||||
hass: HomeAssistant,
|
||||
condition: DeviceCondition
|
||||
) => {
|
||||
): string => {
|
||||
const state = condition.entity_id
|
||||
? hass.states[condition.entity_id]
|
||||
: undefined;
|
||||
@ -127,17 +129,22 @@ export const localizeDeviceAutomationCondition = (
|
||||
"entity_name",
|
||||
state ? computeStateName(state) : condition.entity_id || "<unknown>",
|
||||
"subtype",
|
||||
hass.localize(
|
||||
`component.${condition.domain}.device_automation.condition_subtype.${condition.subtype}`
|
||||
) || condition.subtype
|
||||
) || `"${condition.subtype}" ${condition.type}`
|
||||
condition.subtype
|
||||
? hass.localize(
|
||||
`component.${condition.domain}.device_automation.condition_subtype.${condition.subtype}`
|
||||
) || condition.subtype
|
||||
: ""
|
||||
) ||
|
||||
(condition.subtype
|
||||
? `"${condition.subtype}" ${condition.type}`
|
||||
: condition.type!)
|
||||
);
|
||||
};
|
||||
|
||||
export const localizeDeviceAutomationTrigger = (
|
||||
hass: HomeAssistant,
|
||||
trigger: DeviceTrigger
|
||||
) => {
|
||||
): string => {
|
||||
const state = trigger.entity_id ? hass.states[trigger.entity_id] : undefined;
|
||||
return (
|
||||
hass.localize(
|
||||
@ -145,9 +152,12 @@ export const localizeDeviceAutomationTrigger = (
|
||||
"entity_name",
|
||||
state ? computeStateName(state) : trigger.entity_id || "<unknown>",
|
||||
"subtype",
|
||||
hass.localize(
|
||||
`component.${trigger.domain}.device_automation.trigger_subtype.${trigger.subtype}`
|
||||
) || trigger.subtype
|
||||
) || `"${trigger.subtype}" ${trigger.type}`
|
||||
trigger.subtype
|
||||
? hass.localize(
|
||||
`component.${trigger.domain}.device_automation.trigger_subtype.${trigger.subtype}`
|
||||
) || trigger.subtype
|
||||
: ""
|
||||
) ||
|
||||
(trigger.subtype ? `"${trigger.subtype}" ${trigger.type}` : trigger.type!)
|
||||
);
|
||||
};
|
||||
|
@ -17,6 +17,10 @@ export interface DeviceRegistryEntry {
|
||||
name_by_user?: string;
|
||||
}
|
||||
|
||||
export interface DeviceEntityLookup {
|
||||
[deviceId: string]: EntityRegistryEntry[];
|
||||
}
|
||||
|
||||
export interface DeviceRegistryEntryMutableParams {
|
||||
area_id?: string | null;
|
||||
name_by_user?: string | null;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
import { navigate } from "../common/navigate";
|
||||
|
||||
export const defaultRadiusColor = "#FF9800";
|
||||
export const homeRadiusColor: string = "#03a9f4";
|
||||
@ -48,3 +49,19 @@ export const deleteZone = (hass: HomeAssistant, zoneId: string) =>
|
||||
type: "zone/delete",
|
||||
zone_id: zoneId,
|
||||
});
|
||||
|
||||
let inititialZoneEditorData: Partial<ZoneMutableParams> | undefined;
|
||||
|
||||
export const showZoneEditor = (
|
||||
el: HTMLElement,
|
||||
data?: Partial<ZoneMutableParams>
|
||||
) => {
|
||||
inititialZoneEditorData = data;
|
||||
navigate(el, "/config/zone/new");
|
||||
};
|
||||
|
||||
export const getZoneEditorInitData = () => {
|
||||
const data = inititialZoneEditorData;
|
||||
inititialZoneEditorData = undefined;
|
||||
return data;
|
||||
};
|
||||
|
@ -7,8 +7,8 @@ import {
|
||||
DataEntryFlowStepForm,
|
||||
DataEntryFlowStep,
|
||||
DataEntryFlowStepAbort,
|
||||
FieldSchema,
|
||||
} from "../../data/data_entry_flow";
|
||||
import { HaFormSchema } from "../../components/ha-form/ha-form";
|
||||
|
||||
export interface FlowConfig {
|
||||
loadDevicesAndAreas: boolean;
|
||||
@ -45,7 +45,7 @@ export interface FlowConfig {
|
||||
renderShowFormStepFieldLabel(
|
||||
hass: HomeAssistant,
|
||||
step: DataEntryFlowStepForm,
|
||||
field: FieldSchema
|
||||
field: HaFormSchema
|
||||
): string;
|
||||
|
||||
renderShowFormStepFieldError(
|
||||
|
@ -18,8 +18,10 @@ import "../../resources/ha-style";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { configFlowContentStyles } from "./styles";
|
||||
import { DataEntryFlowStepForm, FieldSchema } from "../../data/data_entry_flow";
|
||||
import { DataEntryFlowStepForm } from "../../data/data_entry_flow";
|
||||
import { FlowConfig } from "./show-dialog-data-entry-flow";
|
||||
// tslint:disable-next-line
|
||||
import { HaFormSchema } from "../../components/ha-form/ha-form";
|
||||
|
||||
@customElement("step-flow-form")
|
||||
class StepFlowForm extends LitElement {
|
||||
@ -176,7 +178,7 @@ class StepFlowForm extends LitElement {
|
||||
this._stepData = ev.detail.value;
|
||||
}
|
||||
|
||||
private _labelCallback = (field: FieldSchema): string =>
|
||||
private _labelCallback = (field: HaFormSchema): string =>
|
||||
this.flowConfig.renderShowFormStepFieldLabel(this.hass, this.step, field);
|
||||
|
||||
private _errorCallback = (error: string) =>
|
||||
|
@ -20,6 +20,7 @@ import "../../common/search/search-input";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { FlowConfig } from "./show-dialog-data-entry-flow";
|
||||
import { configFlowContentStyles } from "./styles";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
|
||||
interface HandlerObj {
|
||||
name: string;
|
||||
@ -69,7 +70,10 @@ class StepFlowPickHandler extends LitElement {
|
||||
.filter=${this.filter}
|
||||
@value-changed=${this._filterChanged}
|
||||
></search-input>
|
||||
<div style=${styleMap({ width: `${this._width}px` })}>
|
||||
<div
|
||||
style=${styleMap({ width: `${this._width}px` })}
|
||||
class=${classMap({ advanced: Boolean(this.showAdvanced) })}
|
||||
>
|
||||
${handlers.map(
|
||||
(handler: HandlerObj) =>
|
||||
html`
|
||||
@ -143,6 +147,14 @@ class StepFlowPickHandler extends LitElement {
|
||||
overflow: auto;
|
||||
max-height: 600px;
|
||||
}
|
||||
@media all and (max-height: 1px) {
|
||||
div {
|
||||
max-height: calc(100vh - 205px);
|
||||
}
|
||||
div.advanced {
|
||||
max-height: calc(100vh - 300px);
|
||||
}
|
||||
}
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import "@material/mwc-button";
|
||||
import "../../../components/ha-relative-time";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { triggerAutomation } from "../../../data/automation";
|
||||
|
||||
@customElement("more-info-automation")
|
||||
class MoreInfoAutomation extends LitElement {
|
||||
@ -42,9 +43,7 @@ class MoreInfoAutomation extends LitElement {
|
||||
}
|
||||
|
||||
private handleAction() {
|
||||
this.hass.callService("automation", "trigger", {
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
});
|
||||
triggerAutomation(this.hass, this.stateObj!.entity_id);
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
|
@ -16,6 +16,7 @@ import "./more-info-input_datetime";
|
||||
import "./more-info-light";
|
||||
import "./more-info-lock";
|
||||
import "./more-info-media_player";
|
||||
import "./more-info-person";
|
||||
import "./more-info-script";
|
||||
import "./more-info-sun";
|
||||
import "./more-info-timer";
|
||||
|
85
src/dialogs/more-info/controls/more-info-person.ts
Normal file
85
src/dialogs/more-info/controls/more-info-person.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
TemplateResult,
|
||||
CSSResult,
|
||||
css,
|
||||
property,
|
||||
customElement,
|
||||
} from "lit-element";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import "@material/mwc-button";
|
||||
|
||||
import "../../../components/map/ha-map";
|
||||
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { showZoneEditor } from "../../../data/zone";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
|
||||
@customElement("more-info-person")
|
||||
class MoreInfoPerson extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public stateObj?: HassEntity;
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.hass || !this.stateObj) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-attributes
|
||||
.stateObj=${this.stateObj}
|
||||
extraFilters="id,user_id,editable"
|
||||
></ha-attributes>
|
||||
${this.stateObj.attributes.latitude && this.stateObj.attributes.longitude
|
||||
? html`
|
||||
<ha-map
|
||||
.hass=${this.hass}
|
||||
.entities=${[this.stateObj.entity_id]}
|
||||
></ha-map>
|
||||
`
|
||||
: ""}
|
||||
${this.hass.user?.is_admin &&
|
||||
this.stateObj.state === "not_home" &&
|
||||
this.stateObj.attributes.latitude &&
|
||||
this.stateObj.attributes.longitude
|
||||
? html`
|
||||
<div class="actions">
|
||||
<mwc-button @click=${this._handleAction}>
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.more_info_control.person.create_zone"
|
||||
)}
|
||||
</mwc-button>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleAction() {
|
||||
showZoneEditor(this, {
|
||||
latitude: this.stateObj!.attributes.latitude,
|
||||
longitude: this.stateObj!.attributes.longitude,
|
||||
});
|
||||
fireEvent(this, "hass-more-info", { entityId: null });
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
.flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.actions {
|
||||
margin: 36px 0 8px 0;
|
||||
text-align: right;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"more-info-person": MoreInfoPerson;
|
||||
}
|
||||
}
|
@ -123,12 +123,15 @@ class MoreInfoVacuum extends LitElement {
|
||||
: ""}
|
||||
${supportsFeature(stateObj, VACUUM_SUPPORT_BATTERY)
|
||||
? html`
|
||||
<div">
|
||||
<div>
|
||||
<span>
|
||||
<iron-icon .icon=${stateObj.attributes.battery_icon}></iron-icon>
|
||||
${stateObj.attributes.battery_level} %
|
||||
</span>
|
||||
</div>`
|
||||
<iron-icon
|
||||
.icon=${stateObj.attributes.battery_icon}
|
||||
></iron-icon>
|
||||
${stateObj.attributes.battery_level}%
|
||||
</span>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
|
||||
|
157
src/layouts/hass-tabs-subpage-data-table.ts
Normal file
157
src/layouts/hass-tabs-subpage-data-table.ts
Normal file
@ -0,0 +1,157 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
query,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "../components/data-table/ha-data-table";
|
||||
// tslint:disable-next-line
|
||||
import {
|
||||
HaDataTable,
|
||||
DataTableColumnContainer,
|
||||
DataTableRowData,
|
||||
} from "../components/data-table/ha-data-table";
|
||||
import "./hass-tabs-subpage";
|
||||
import { HomeAssistant, Route } from "../types";
|
||||
// tslint:disable-next-line
|
||||
import { PageNavigation } from "./hass-tabs-subpage";
|
||||
|
||||
@customElement("hass-tabs-subpage-data-table")
|
||||
export class HaTabsSubpageDataTable extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@property() public isWide!: boolean;
|
||||
@property({ type: Boolean, reflect: true }) public narrow!: boolean;
|
||||
/**
|
||||
* Object with the columns.
|
||||
* @type {Object}
|
||||
*/
|
||||
@property({ type: Object }) public columns: DataTableColumnContainer = {};
|
||||
/**
|
||||
* Data to show in the table.
|
||||
* @type {Array}
|
||||
*/
|
||||
@property({ type: Array }) public data: DataTableRowData[] = [];
|
||||
/**
|
||||
* Should rows be selectable.
|
||||
* @type {Boolean}
|
||||
*/
|
||||
@property({ type: Boolean }) public selectable = false;
|
||||
/**
|
||||
* Field with a unique id per entry in data.
|
||||
* @type {String}
|
||||
*/
|
||||
@property({ type: String }) public id = "id";
|
||||
/**
|
||||
* String to filter the data in the data table on.
|
||||
* @type {String}
|
||||
*/
|
||||
@property({ type: String }) public filter = "";
|
||||
/**
|
||||
* What path to use when the back button is pressed.
|
||||
* @type {String}
|
||||
* @attr back-path
|
||||
*/
|
||||
@property({ type: String, attribute: "back-path" }) public backPath?: string;
|
||||
/**
|
||||
* Function to call when the back button is pressed.
|
||||
* @type {() => void}
|
||||
*/
|
||||
@property() public backCallback?: () => void;
|
||||
@property() public route!: Route;
|
||||
/**
|
||||
* Array of tabs to show on the page.
|
||||
* @type {Array}
|
||||
*/
|
||||
@property() public tabs!: PageNavigation[];
|
||||
@query("ha-data-table") private _dataTable!: HaDataTable;
|
||||
|
||||
public clearSelection() {
|
||||
this._dataTable.clearSelection();
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.backPath=${this.backPath}
|
||||
.backCallback=${this.backCallback}
|
||||
.route=${this.route}
|
||||
.tabs=${this.tabs}
|
||||
>
|
||||
${this.narrow
|
||||
? html`
|
||||
<div slot="header">
|
||||
<slot name="header">
|
||||
<div class="search-toolbar">
|
||||
<search-input
|
||||
no-label-float
|
||||
no-underline
|
||||
@value-changed=${this._handleSearchChange}
|
||||
></search-input>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
<ha-data-table
|
||||
.columns=${this.columns}
|
||||
.data=${this.data}
|
||||
.filter=${this.filter}
|
||||
.selectable=${this.selectable}
|
||||
.id=${this.id}
|
||||
>
|
||||
${!this.narrow
|
||||
? html`
|
||||
<div slot="header">
|
||||
<slot name="header">
|
||||
<slot name="header">
|
||||
<div class="table-header">
|
||||
<search-input
|
||||
no-label-float
|
||||
no-underline
|
||||
@value-changed=${this._handleSearchChange}
|
||||
></search-input></div></slot
|
||||
></slot>
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<div slot="header"></div>
|
||||
`}
|
||||
</ha-data-table>
|
||||
</hass-tabs-subpage>
|
||||
`;
|
||||
}
|
||||
|
||||
private _handleSearchChange(ev: CustomEvent) {
|
||||
this.filter = ev.detail.value;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
ha-data-table {
|
||||
width: 100%;
|
||||
--data-table-border-width: 0;
|
||||
}
|
||||
:host(:not([narrow])) ha-data-table {
|
||||
height: calc(100vh - 65px);
|
||||
display: block;
|
||||
}
|
||||
.table-header {
|
||||
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
|
||||
}
|
||||
.search-toolbar {
|
||||
margin-left: -24px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
search-input {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
@ -56,6 +56,11 @@ class HassTabsSubpage extends LitElement {
|
||||
.hassio=${this.hassio}
|
||||
@click=${this._backTapped}
|
||||
></ha-paper-icon-button-arrow-prev>
|
||||
${this.narrow
|
||||
? html`
|
||||
<div main-title><slot name="header"></slot></div>
|
||||
`
|
||||
: ""}
|
||||
<div id="tabbar" class=${classMap({ "bottom-bar": this.narrow })}>
|
||||
${this.tabs.map((page, index) =>
|
||||
(!page.component ||
|
||||
@ -138,11 +143,6 @@ class HassTabsSubpage extends LitElement {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:host([narrow]) .toolbar {
|
||||
background-color: var(--primary-background-color);
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
#tabbar {
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
|
@ -13,6 +13,8 @@ import { Action } from "../../../../data/script";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import "./ha-automation-action-row";
|
||||
|
||||
import { HaDeviceAction } from "./types/ha-automation-action-device_id";
|
||||
|
||||
@customElement("ha-automation-action")
|
||||
export default class HaAutomationAction extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -46,7 +48,7 @@ export default class HaAutomationAction extends LitElement {
|
||||
|
||||
private _addAction() {
|
||||
const actions = this.actions.concat({
|
||||
service: "",
|
||||
...HaDeviceAction.defaultConfig,
|
||||
});
|
||||
|
||||
fireEvent(this, "value-changed", { value: actions });
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
import "@material/mwc-button";
|
||||
import "../../../../components/ha-card";
|
||||
|
||||
import { HaStateCondition } from "./types/ha-automation-condition-state";
|
||||
import { HaDeviceCondition } from "./types/ha-automation-condition-device";
|
||||
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
@ -48,8 +48,8 @@ export default class HaAutomationCondition extends LitElement {
|
||||
|
||||
private _addCondition() {
|
||||
const conditions = this.conditions.concat({
|
||||
condition: "state",
|
||||
...HaStateCondition.defaultConfig,
|
||||
condition: "device",
|
||||
...HaDeviceCondition.defaultConfig,
|
||||
});
|
||||
|
||||
fireEvent(this, "value-changed", { value: conditions });
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
deleteAutomation,
|
||||
getAutomationEditorInitData,
|
||||
Trigger,
|
||||
triggerAutomation,
|
||||
} from "../../../data/automation";
|
||||
import { Action } from "../../../data/script";
|
||||
import {
|
||||
@ -36,6 +37,8 @@ import "./condition/ha-automation-condition";
|
||||
import "./trigger/ha-automation-trigger";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { HaDeviceAction } from "./action/types/ha-automation-action-device_id";
|
||||
import { HaDeviceTrigger } from "./trigger/types/ha-automation-trigger-device";
|
||||
|
||||
export class HaAutomationEditor extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -74,132 +77,155 @@ export class HaAutomationEditor extends LitElement {
|
||||
<div class="errors">${this._errors}</div>
|
||||
`
|
||||
: ""}
|
||||
<div
|
||||
class="${classMap({
|
||||
rtl: computeRTL(this.hass),
|
||||
})}"
|
||||
>
|
||||
${this._config
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">${this._config.alias}</span>
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.introduction"
|
||||
)}
|
||||
</span>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
)}
|
||||
name="alias"
|
||||
.value=${this._config.alias}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
</paper-input>
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
.value=${this._config.description}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.introduction"
|
||||
${this._config
|
||||
? html`
|
||||
${this.narrow
|
||||
? html`
|
||||
<span slot="header">${this._config?.alias}</span>
|
||||
`
|
||||
: ""}
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
${!this.narrow
|
||||
? html`
|
||||
<span slot="header">${this._config.alias}</span>
|
||||
`
|
||||
: ""}
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.introduction"
|
||||
)}
|
||||
</span>
|
||||
<ha-card>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.alias"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/trigger/"
|
||||
target="_blank"
|
||||
name="alias"
|
||||
.value=${this._config.alias}
|
||||
@value-changed=${this._valueChanged}
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.learn_more"
|
||||
</paper-input>
|
||||
<ha-textarea
|
||||
.label=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.label"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-trigger
|
||||
.triggers=${this._config.trigger}
|
||||
@value-changed=${this._triggerChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-trigger>
|
||||
</ha-config-section>
|
||||
.placeholder=${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.description.placeholder"
|
||||
)}
|
||||
name="description"
|
||||
.value=${this._config.description}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-textarea>
|
||||
</div>
|
||||
${this.creatingNew
|
||||
? ""
|
||||
: html`
|
||||
<div
|
||||
class="card-actions layout horizontal justified center"
|
||||
>
|
||||
<div class="layout horizontal center">
|
||||
<ha-entity-toggle
|
||||
.hass=${this.hass}
|
||||
.stateObj=${this.automation}
|
||||
></ha-entity-toggle>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.enable_disable"
|
||||
)}
|
||||
</div>
|
||||
<mwc-button @click=${this._excuteAutomation}>
|
||||
${this.hass.localize("ui.card.automation.trigger")}
|
||||
</mwc-button>
|
||||
</div>
|
||||
`}
|
||||
</ha-card>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.header"
|
||||
"ui.panel.config.automation.editor.triggers.introduction"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/scripts/conditions/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-condition
|
||||
.conditions=${this._config.condition || []}
|
||||
@value-changed=${this._conditionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-condition>
|
||||
</ha-config-section>
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/trigger/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.triggers.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-trigger
|
||||
.triggers=${this._config.trigger}
|
||||
@value-changed=${this._triggerChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-trigger>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.header"
|
||||
"ui.panel.config.automation.editor.conditions.introduction"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/action/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-action
|
||||
.actions=${this._config.action}
|
||||
@value-changed=${this._actionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-action>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/scripts/conditions/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.conditions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-condition
|
||||
.conditions=${this._config.condition || []}
|
||||
@value-changed=${this._conditionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-condition>
|
||||
</ha-config-section>
|
||||
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.header"
|
||||
)}
|
||||
</span>
|
||||
<span slot="introduction">
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.introduction"
|
||||
)}
|
||||
</p>
|
||||
<a
|
||||
href="https://home-assistant.io/docs/automation/action/"
|
||||
target="_blank"
|
||||
>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.automation.editor.actions.learn_more"
|
||||
)}
|
||||
</a>
|
||||
</span>
|
||||
<ha-automation-action
|
||||
.actions=${this._config.action}
|
||||
@value-changed=${this._actionChanged}
|
||||
.hass=${this.hass}
|
||||
></ha-automation-action>
|
||||
</ha-config-section>
|
||||
`
|
||||
: ""}
|
||||
<ha-fab
|
||||
?is-wide="${this.isWide}"
|
||||
?narrow="${this.narrow}"
|
||||
@ -273,9 +299,9 @@ export class HaAutomationEditor extends LitElement {
|
||||
"ui.panel.config.automation.editor.default_name"
|
||||
),
|
||||
description: "",
|
||||
trigger: [{ platform: "state" }],
|
||||
trigger: [{ platform: "device", ...HaDeviceTrigger.defaultConfig }],
|
||||
condition: [],
|
||||
action: [{ service: "" }],
|
||||
action: [{ ...HaDeviceAction.defaultConfig }],
|
||||
...initData,
|
||||
};
|
||||
}
|
||||
@ -317,6 +343,10 @@ export class HaAutomationEditor extends LitElement {
|
||||
this._dirty = true;
|
||||
}
|
||||
|
||||
private _excuteAutomation() {
|
||||
triggerAutomation(this.hass, this.automation.entity_id);
|
||||
}
|
||||
|
||||
private _backTapped(): void {
|
||||
if (this._dirty) {
|
||||
showConfirmationDialog(this, {
|
||||
@ -389,6 +419,9 @@ export class HaAutomationEditor extends LitElement {
|
||||
span[slot="introduction"] a {
|
||||
color: var(--primary-color);
|
||||
}
|
||||
ha-entity-toggle {
|
||||
margin-right: 8px;
|
||||
}
|
||||
ha-fab {
|
||||
position: fixed;
|
||||
bottom: 16px;
|
||||
|
@ -13,7 +13,7 @@ import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
|
||||
import "./ha-automation-trigger-row";
|
||||
import { HaStateTrigger } from "./types/ha-automation-trigger-state";
|
||||
import { HaDeviceTrigger } from "./types/ha-automation-trigger-device";
|
||||
import { Trigger } from "../../../../data/automation";
|
||||
|
||||
@customElement("ha-automation-trigger")
|
||||
@ -47,8 +47,8 @@ export default class HaAutomationTrigger extends LitElement {
|
||||
|
||||
private _addTrigger() {
|
||||
const triggers = this.triggers.concat({
|
||||
platform: "state",
|
||||
...HaStateTrigger.defaultConfig,
|
||||
platform: "device",
|
||||
...HaDeviceTrigger.defaultConfig,
|
||||
});
|
||||
|
||||
fireEvent(this, "value-changed", { value: triggers });
|
||||
|
@ -76,7 +76,7 @@ export class DialogDeviceAutomation extends LitElement {
|
||||
<ha-dialog
|
||||
open
|
||||
@closing="${this._close}"
|
||||
.title=${this.hass.localize(
|
||||
.heading=${this.hass.localize(
|
||||
`ui.panel.config.devices.${
|
||||
this._params.script ? "script" : "automation"
|
||||
}.create`
|
||||
|
@ -152,6 +152,7 @@ export class HaDeviceEntitiesCard extends LitElement {
|
||||
const entry = (ev.currentTarget! as any).entry;
|
||||
showEntityRegistryDetailDialog(this, {
|
||||
entry,
|
||||
entity_id: entry.entity_id,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,14 @@ export class HaConfigDevicePage extends LitElement {
|
||||
.tabs=${configSections.integrations}
|
||||
.route=${this.route}
|
||||
>
|
||||
${
|
||||
this.narrow
|
||||
? html`
|
||||
<span slot="header">${device.name_by_user || device.name}</span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
|
||||
<paper-icon-button
|
||||
slot="toolbar-icon"
|
||||
icon="hass:settings"
|
||||
@ -130,7 +138,13 @@ export class HaConfigDevicePage extends LitElement {
|
||||
<div class="container">
|
||||
<div class="left">
|
||||
<div class="device-info">
|
||||
<h1>${device.name_by_user || device.name}</h1>
|
||||
${
|
||||
this.narrow
|
||||
? ""
|
||||
: html`
|
||||
<h1>${device.name_by_user || device.name}</h1>
|
||||
`
|
||||
}
|
||||
<ha-device-card
|
||||
.hass=${this.hass}
|
||||
.areas=${this.areas}
|
||||
@ -498,6 +512,10 @@ export class HaConfigDevicePage extends LitElement {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
:host([narrow]) .container > *:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
:host([narrow]) .container {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "./ha-devices-data-table";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
|
||||
import {
|
||||
LitElement,
|
||||
@ -11,11 +10,24 @@ import {
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
computeDeviceName,
|
||||
DeviceEntityLookup,
|
||||
} from "../../../data/device_registry";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { ConfigEntry } from "../../../data/config_entries";
|
||||
import { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { LocalizeFunc } from "../../../common/translations/localize";
|
||||
import { DeviceRowData } from "./ha-devices-data-table";
|
||||
import {
|
||||
DataTableColumnContainer,
|
||||
DataTableRowData,
|
||||
RowClickedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
|
||||
@customElement("ha-config-devices-dashboard")
|
||||
export class HaConfigDeviceDashboard extends LitElement {
|
||||
@ -29,30 +41,219 @@ export class HaConfigDeviceDashboard extends LitElement {
|
||||
@property() public domain!: string;
|
||||
@property() public route!: Route;
|
||||
|
||||
private _devices = memoizeOne(
|
||||
(
|
||||
devices: DeviceRegistryEntry[],
|
||||
entries: ConfigEntry[],
|
||||
entities: EntityRegistryEntry[],
|
||||
areas: AreaRegistryEntry[],
|
||||
domain: string,
|
||||
localize: LocalizeFunc
|
||||
) => {
|
||||
// Some older installations might have devices pointing at invalid entryIDs
|
||||
// So we guard for that.
|
||||
|
||||
let outputDevices: DeviceRowData[] = devices;
|
||||
|
||||
const deviceLookup: { [deviceId: string]: DeviceRegistryEntry } = {};
|
||||
for (const device of devices) {
|
||||
deviceLookup[device.id] = device;
|
||||
}
|
||||
|
||||
const deviceEntityLookup: DeviceEntityLookup = {};
|
||||
for (const entity of entities) {
|
||||
if (!entity.device_id) {
|
||||
continue;
|
||||
}
|
||||
if (!(entity.device_id in deviceEntityLookup)) {
|
||||
deviceEntityLookup[entity.device_id] = [];
|
||||
}
|
||||
deviceEntityLookup[entity.device_id].push(entity);
|
||||
}
|
||||
|
||||
const entryLookup: { [entryId: string]: ConfigEntry } = {};
|
||||
for (const entry of entries) {
|
||||
entryLookup[entry.entry_id] = entry;
|
||||
}
|
||||
|
||||
const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
|
||||
for (const area of areas) {
|
||||
areaLookup[area.area_id] = area;
|
||||
}
|
||||
|
||||
if (domain) {
|
||||
outputDevices = outputDevices.filter((device) =>
|
||||
device.config_entries.find(
|
||||
(entryId) =>
|
||||
entryId in entryLookup && entryLookup[entryId].domain === domain
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
outputDevices = outputDevices.map((device) => {
|
||||
return {
|
||||
...device,
|
||||
name: computeDeviceName(
|
||||
device,
|
||||
this.hass,
|
||||
deviceEntityLookup[device.id]
|
||||
),
|
||||
model: device.model || "<unknown>",
|
||||
manufacturer: device.manufacturer || "<unknown>",
|
||||
area: device.area_id ? areaLookup[device.area_id].name : "No area",
|
||||
integration: device.config_entries.length
|
||||
? device.config_entries
|
||||
.filter((entId) => entId in entryLookup)
|
||||
.map(
|
||||
(entId) =>
|
||||
localize(
|
||||
`component.${entryLookup[entId].domain}.config.title`
|
||||
) || entryLookup[entId].domain
|
||||
)
|
||||
.join(", ")
|
||||
: "No integration",
|
||||
battery_entity: this._batteryEntity(device.id, deviceEntityLookup),
|
||||
};
|
||||
});
|
||||
|
||||
return outputDevices;
|
||||
}
|
||||
);
|
||||
|
||||
private _columns = memoizeOne(
|
||||
(narrow: boolean): DataTableColumnContainer =>
|
||||
narrow
|
||||
? {
|
||||
name: {
|
||||
title: "Device",
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
template: (name, device: DataTableRowData) => {
|
||||
const battery = device.battery_entity
|
||||
? this.hass.states[device.battery_entity]
|
||||
: undefined;
|
||||
// Have to work on a nice layout for mobile
|
||||
return html`
|
||||
${name}<br />
|
||||
${device.area} | ${device.integration}<br />
|
||||
${battery && !isNaN(battery.state as any)
|
||||
? html`
|
||||
${battery.state}%
|
||||
<ha-state-icon
|
||||
.hass=${this.hass!}
|
||||
.stateObj=${battery}
|
||||
></ha-state-icon>
|
||||
`
|
||||
: ""}
|
||||
`;
|
||||
},
|
||||
},
|
||||
}
|
||||
: {
|
||||
name: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.devices.data_table.device"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
direction: "asc",
|
||||
},
|
||||
manufacturer: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.devices.data_table.manufacturer"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
},
|
||||
model: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.devices.data_table.model"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
},
|
||||
area: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.devices.data_table.area"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
},
|
||||
integration: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.devices.data_table.integration"
|
||||
),
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
},
|
||||
battery_entity: {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.devices.data_table.battery"
|
||||
),
|
||||
sortable: true,
|
||||
type: "numeric",
|
||||
template: (batteryEntity: string) => {
|
||||
const battery = batteryEntity
|
||||
? this.hass.states[batteryEntity]
|
||||
: undefined;
|
||||
return battery && !isNaN(battery.state as any)
|
||||
? html`
|
||||
${battery.state}%
|
||||
<ha-state-icon
|
||||
.hass=${this.hass!}
|
||||
.stateObj=${battery}
|
||||
></ha-state-icon>
|
||||
`
|
||||
: html`
|
||||
-
|
||||
`;
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
<hass-tabs-subpage-data-table
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.tabs=${configSections.integrations}
|
||||
.route=${this.route}
|
||||
.columns=${this._columns(this.narrow)}
|
||||
.data=${this._devices(
|
||||
this.devices,
|
||||
this.entries,
|
||||
this.entities,
|
||||
this.areas,
|
||||
this.domain,
|
||||
this.hass.localize
|
||||
)}
|
||||
@row-click=${this._handleRowClicked}
|
||||
>
|
||||
<div class="content">
|
||||
<ha-devices-data-table
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.devices=${this.devices}
|
||||
.entries=${this.entries}
|
||||
.entities=${this.entities}
|
||||
.areas=${this.areas}
|
||||
.domain=${this.domain}
|
||||
></ha-devices-data-table>
|
||||
</div>
|
||||
</hass-tabs-subpage>
|
||||
</hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
||||
private _batteryEntity(
|
||||
deviceId: string,
|
||||
deviceEntityLookup: DeviceEntityLookup
|
||||
): string | undefined {
|
||||
const batteryEntity = (deviceEntityLookup[deviceId] || []).find(
|
||||
(entity) =>
|
||||
this.hass.states[entity.entity_id] &&
|
||||
this.hass.states[entity.entity_id].attributes.device_class === "battery"
|
||||
);
|
||||
|
||||
return batteryEntity ? batteryEntity.entity_id : undefined;
|
||||
}
|
||||
|
||||
private _handleRowClicked(ev: CustomEvent) {
|
||||
const deviceId = (ev.detail as RowClickedEvent).id;
|
||||
navigate(this, `/config/devices/device/${deviceId}`);
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
.content {
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
import {
|
||||
DeviceRegistryEntry,
|
||||
computeDeviceName,
|
||||
DeviceEntityLookup,
|
||||
} from "../../../data/device_registry";
|
||||
import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { ConfigEntry } from "../../../data/config_entries";
|
||||
@ -35,10 +36,6 @@ export interface DeviceRowData extends DeviceRegistryEntry {
|
||||
battery_entity?: string;
|
||||
}
|
||||
|
||||
export interface DeviceEntityLookup {
|
||||
[deviceId: string]: EntityRegistryEntry[];
|
||||
}
|
||||
|
||||
@customElement("ha-devices-data-table")
|
||||
export class HaDevicesDataTable extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
@ -51,7 +51,8 @@ export class DialogEntityRegistryDetail extends LitElement {
|
||||
return html``;
|
||||
}
|
||||
const entry = this._params.entry;
|
||||
const stateObj: HassEntity | undefined = this.hass.states[entry.entity_id];
|
||||
const entityId = this._params.entity_id;
|
||||
const stateObj: HassEntity | undefined = this.hass.states[entityId];
|
||||
|
||||
return html`
|
||||
<ha-paper-dialog
|
||||
@ -68,9 +69,7 @@ export class DialogEntityRegistryDetail extends LitElement {
|
||||
dialog-dismiss
|
||||
></paper-icon-button>
|
||||
<div class="main-title" main-title>
|
||||
${stateObj
|
||||
? computeStateName(stateObj)
|
||||
: entry.name || entry.entity_id}
|
||||
${stateObj ? computeStateName(stateObj) : entry?.name || entityId}
|
||||
</div>
|
||||
${stateObj
|
||||
? html`
|
||||
@ -99,20 +98,28 @@ export class DialogEntityRegistryDetail extends LitElement {
|
||||
</paper-tabs>
|
||||
${cache(
|
||||
this._curTab === "tab-settings"
|
||||
? html`
|
||||
<entity-registry-settings
|
||||
.hass=${this.hass}
|
||||
.entry=${entry}
|
||||
.dialogElement=${this._dialog}
|
||||
@close-dialog=${this._closeDialog}
|
||||
></entity-registry-settings>
|
||||
`
|
||||
? entry
|
||||
? html`
|
||||
<entity-registry-settings
|
||||
.hass=${this.hass}
|
||||
.entry=${entry}
|
||||
.dialogElement=${this._dialog}
|
||||
@close-dialog=${this._closeDialog}
|
||||
></entity-registry-settings>
|
||||
`
|
||||
: html`
|
||||
<paper-dialog-scrollable>
|
||||
${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.no_unique_id"
|
||||
)}
|
||||
</paper-dialog-scrollable>
|
||||
`
|
||||
: this._curTab === "tab-related"
|
||||
? html`
|
||||
<paper-dialog-scrollable>
|
||||
<ha-related-items
|
||||
.hass=${this.hass}
|
||||
.itemId=${entry.entity_id}
|
||||
.itemId=${entityId}
|
||||
itemType="entity"
|
||||
@close-dialog=${this._closeDialog}
|
||||
></ha-related-items>
|
||||
@ -139,7 +146,7 @@ export class DialogEntityRegistryDetail extends LitElement {
|
||||
|
||||
private _openMoreInfo(): void {
|
||||
fireEvent(this, "hass-more-info", {
|
||||
entityId: this._params!.entry.entity_id,
|
||||
entityId: this._params!.entity_id,
|
||||
});
|
||||
this._params = undefined;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
|
||||
import "@polymer/paper-item/paper-icon-item";
|
||||
import "@polymer/paper-listbox/paper-listbox";
|
||||
import "@polymer/paper-tooltip/paper-tooltip";
|
||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import { UnsubscribeFunc, HassEntities } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -19,16 +19,14 @@ import memoize from "memoize-one";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { domainIcon } from "../../../common/entity/domain_icon";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import "../../../components/data-table/ha-data-table";
|
||||
// tslint:disable-next-line
|
||||
import {
|
||||
DataTableColumnContainer,
|
||||
DataTableColumnData,
|
||||
HaDataTable,
|
||||
RowClickedEvent,
|
||||
SelectionChangedEvent,
|
||||
} from "../../../components/data-table/ha-data-table";
|
||||
import "../../../components/ha-icon";
|
||||
import "../../../common/search/search-input";
|
||||
import {
|
||||
computeEntityRegistryName,
|
||||
EntityRegistryEntry,
|
||||
@ -38,7 +36,7 @@ import {
|
||||
} from "../../../data/entity_registry";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../layouts/hass-loading-screen";
|
||||
import "../../../layouts/hass-tabs-subpage";
|
||||
import "../../../layouts/hass-tabs-subpage-data-table";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { HomeAssistant, Route } from "../../../types";
|
||||
import { DialogEntityRegistryDetail } from "./dialog-entity-registry-detail";
|
||||
@ -47,6 +45,21 @@ import {
|
||||
showEntityRegistryDetailDialog,
|
||||
} from "./show-dialog-entity-registry-detail";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
// tslint:disable-next-line: no-duplicate-imports
|
||||
import { HaTabsSubpageDataTable } from "../../../layouts/hass-tabs-subpage-data-table";
|
||||
|
||||
export interface StateEntity extends EntityRegistryEntry {
|
||||
readonly?: boolean;
|
||||
selectable?: boolean;
|
||||
}
|
||||
|
||||
export interface EntityRow extends StateEntity {
|
||||
icon: string;
|
||||
unavailable: boolean;
|
||||
status: string;
|
||||
}
|
||||
|
||||
@customElement("ha-config-entities")
|
||||
export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
@ -57,9 +70,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
@property() private _entities?: EntityRegistryEntry[];
|
||||
@property() private _showDisabled = false;
|
||||
@property() private _showUnavailable = true;
|
||||
@property() private _showReadOnly = true;
|
||||
@property() private _filter = "";
|
||||
@property() private _selectedEntities: string[] = [];
|
||||
@query("ha-data-table") private _dataTable!: HaDataTable;
|
||||
@query("hass-tabs-subpage-data-table")
|
||||
private _dataTable!: HaTabsSubpageDataTable;
|
||||
private getDialog?: () => DialogEntityRegistryDetail | undefined;
|
||||
|
||||
private _columns = memoize(
|
||||
@ -90,7 +105,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
sortable: true,
|
||||
filterable: true,
|
||||
template: (_status, entity: any) =>
|
||||
entity.unavailable || entity.disabled_by
|
||||
entity.unavailable || entity.disabled_by || entity.readonly
|
||||
? html`
|
||||
<div
|
||||
tabindex="0"
|
||||
@ -102,15 +117,21 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
})}
|
||||
.icon=${entity.unavailable
|
||||
? "hass:alert-circle"
|
||||
: "hass:cancel"}
|
||||
: entity.disabled_by
|
||||
? "hass:cancel"
|
||||
: "hass:pencil-off"}
|
||||
></ha-icon>
|
||||
<paper-tooltip position="left">
|
||||
${entity.unavailable
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.entities.picker.status.unavailable"
|
||||
)
|
||||
: this.hass.localize(
|
||||
: entity.disabled_by
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.entities.picker.status.disabled"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.entities.picker.status.readonly"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
</div>
|
||||
@ -156,21 +177,43 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
private _filteredEntities = memoize(
|
||||
(
|
||||
entities: EntityRegistryEntry[],
|
||||
states: HassEntities,
|
||||
showDisabled: boolean,
|
||||
showUnavailable: boolean
|
||||
) => {
|
||||
showUnavailable: boolean,
|
||||
showReadOnly: boolean
|
||||
): EntityRow[] => {
|
||||
const stateEntities: StateEntity[] = [];
|
||||
if (showReadOnly) {
|
||||
const regEntityIds = new Set(
|
||||
entities.map((entity) => entity.entity_id)
|
||||
);
|
||||
for (const entityId of Object.keys(states)) {
|
||||
if (regEntityIds.has(entityId)) {
|
||||
continue;
|
||||
}
|
||||
stateEntities.push({
|
||||
name: computeStateName(states[entityId]),
|
||||
entity_id: entityId,
|
||||
platform: computeDomain(entityId),
|
||||
disabled_by: null,
|
||||
readonly: true,
|
||||
selectable: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!showDisabled) {
|
||||
entities = entities.filter((entity) => !Boolean(entity.disabled_by));
|
||||
}
|
||||
|
||||
return entities.reduce((result, entry) => {
|
||||
const state = this.hass!.states[entry.entity_id];
|
||||
const result: EntityRow[] = [];
|
||||
|
||||
const unavailable =
|
||||
state && (state.state === "unavailable" || state.attributes.restored); // if there is not state it is disabled
|
||||
for (const entry of entities.concat(stateEntities)) {
|
||||
const state = states[entry.entity_id];
|
||||
const unavailable = state?.state === "unavailable";
|
||||
|
||||
if (!showUnavailable && unavailable) {
|
||||
return result;
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push({
|
||||
@ -192,8 +235,9 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
)
|
||||
: this.hass.localize("ui.panel.config.entities.picker.status.ok"),
|
||||
});
|
||||
return result;
|
||||
}, [] as any);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
);
|
||||
|
||||
@ -223,154 +267,147 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
<hass-loading-screen></hass-loading-screen>
|
||||
`;
|
||||
}
|
||||
const headerToolbar = this._selectedEntities.length
|
||||
? html`
|
||||
<p class="selected-txt">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.selected",
|
||||
"number",
|
||||
this._selectedEntities.length
|
||||
)}
|
||||
</p>
|
||||
<div class="header-btns">
|
||||
${!this.narrow
|
||||
? html`
|
||||
<mwc-button @click=${this._enableSelected}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.enable_selected.button"
|
||||
)}</mwc-button
|
||||
>
|
||||
<mwc-button @click=${this._disableSelected}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.disable_selected.button"
|
||||
)}</mwc-button
|
||||
>
|
||||
<mwc-button @click=${this._removeSelected}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.remove_selected.button"
|
||||
)}</mwc-button
|
||||
>
|
||||
`
|
||||
: html`
|
||||
<paper-icon-button
|
||||
id="enable-btn"
|
||||
icon="hass:undo"
|
||||
@click=${this._enableSelected}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip for="enable-btn">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.enable_selected.button"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
<paper-icon-button
|
||||
id="disable-btn"
|
||||
icon="hass:cancel"
|
||||
@click=${this._disableSelected}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip for="disable-btn">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.disable_selected.button"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
<paper-icon-button
|
||||
id="remove-btn"
|
||||
icon="hass:delete"
|
||||
@click=${this._removeSelected}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip for="remove-btn">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.remove_selected.button"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
`}
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<search-input
|
||||
no-label-float
|
||||
no-underline
|
||||
@value-changed=${this._handleSearchChange}
|
||||
.filter=${this._filter}
|
||||
></search-input>
|
||||
<paper-menu-button no-animations horizontal-align="right">
|
||||
<paper-icon-button
|
||||
aria-label=${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.filter"
|
||||
)}
|
||||
title="${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.filter"
|
||||
)}"
|
||||
icon="hass:filter-variant"
|
||||
slot="dropdown-trigger"
|
||||
></paper-icon-button>
|
||||
<paper-listbox slot="dropdown-content">
|
||||
<paper-icon-item @tap="${this._showDisabledChanged}">
|
||||
<paper-checkbox
|
||||
.checked=${this._showDisabled}
|
||||
slot="item-icon"
|
||||
></paper-checkbox>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.show_disabled"
|
||||
)}
|
||||
</paper-icon-item>
|
||||
<paper-icon-item @tap="${this._showRestoredChanged}">
|
||||
<paper-checkbox
|
||||
.checked=${this._showUnavailable}
|
||||
slot="item-icon"
|
||||
></paper-checkbox>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.show_unavailable"
|
||||
)}
|
||||
</paper-icon-item>
|
||||
<paper-icon-item @tap="${this._showReadOnlyChanged}">
|
||||
<paper-checkbox
|
||||
.checked=${this._showReadOnly}
|
||||
slot="item-icon"
|
||||
></paper-checkbox>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.show_readonly"
|
||||
)}
|
||||
</paper-icon-item>
|
||||
</paper-listbox>
|
||||
</paper-menu-button>
|
||||
`;
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
<hass-tabs-subpage-data-table
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
back-path="/config"
|
||||
.route=${this.route}
|
||||
.tabs=${configSections.integrations}
|
||||
.columns=${this._columns(this.narrow, this.hass.language)}
|
||||
.data=${this._filteredEntities(
|
||||
this._entities,
|
||||
this.hass.states,
|
||||
this._showDisabled,
|
||||
this._showUnavailable,
|
||||
this._showReadOnly
|
||||
)}
|
||||
.filter=${this._filter}
|
||||
selectable
|
||||
@selection-changed=${this._handleSelectionChanged}
|
||||
@row-click=${this._openEditEntry}
|
||||
id="entity_id"
|
||||
>
|
||||
<div class="content">
|
||||
<div class="intro">
|
||||
<h2>
|
||||
${this.hass.localize("ui.panel.config.entities.picker.header")}
|
||||
</h2>
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.introduction"
|
||||
)}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.introduction2"
|
||||
)}
|
||||
</p>
|
||||
<a href="/config/integrations">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.integrations_page"
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
<ha-data-table
|
||||
.columns=${this._columns(this.narrow, this.hass.language)}
|
||||
.data=${this._filteredEntities(
|
||||
this._entities,
|
||||
this._showDisabled,
|
||||
this._showUnavailable
|
||||
)}
|
||||
.filter=${this._filter}
|
||||
selectable
|
||||
@selection-changed=${this._handleSelectionChanged}
|
||||
@row-click=${this._openEditEntry}
|
||||
id="entity_id"
|
||||
>
|
||||
<div class="table-header" slot="header">
|
||||
${this._selectedEntities.length
|
||||
? html`
|
||||
<p class="selected-txt">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.selected",
|
||||
"number",
|
||||
this._selectedEntities.length
|
||||
)}
|
||||
</p>
|
||||
<div class="header-btns">
|
||||
${!this.narrow
|
||||
? html`
|
||||
<mwc-button @click=${this._enableSelected}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.enable_selected.button"
|
||||
)}</mwc-button
|
||||
>
|
||||
<mwc-button @click=${this._disableSelected}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.disable_selected.button"
|
||||
)}</mwc-button
|
||||
>
|
||||
<mwc-button @click=${this._removeSelected}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.remove_selected.button"
|
||||
)}</mwc-button
|
||||
>
|
||||
`
|
||||
: html`
|
||||
<paper-icon-button
|
||||
id="enable-btn"
|
||||
icon="hass:undo"
|
||||
@click=${this._enableSelected}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip for="enable-btn">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.enable_selected.button"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
<paper-icon-button
|
||||
id="disable-btn"
|
||||
icon="hass:cancel"
|
||||
@click=${this._disableSelected}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip for="disable-btn">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.disable_selected.button"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
<paper-icon-button
|
||||
id="remove-btn"
|
||||
icon="hass:delete"
|
||||
@click=${this._removeSelected}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip for="remove-btn">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.entities.picker.remove_selected.button"
|
||||
)}
|
||||
</paper-tooltip>
|
||||
`}
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<search-input
|
||||
@value-changed=${this._handleSearchChange}
|
||||
.filter=${this._filter}
|
||||
></search-input>
|
||||
<paper-menu-button no-animations horizontal-align="right">
|
||||
<paper-icon-button
|
||||
aria-label=${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.filter"
|
||||
)}
|
||||
title="${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.filter"
|
||||
)}"
|
||||
icon="hass:filter-variant"
|
||||
slot="dropdown-trigger"
|
||||
></paper-icon-button>
|
||||
<paper-listbox slot="dropdown-content">
|
||||
<paper-icon-item @tap="${this._showDisabledChanged}">
|
||||
<paper-checkbox
|
||||
.checked=${this._showDisabled}
|
||||
slot="item-icon"
|
||||
></paper-checkbox>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.show_disabled"
|
||||
)}
|
||||
</paper-icon-item>
|
||||
<paper-icon-item @tap="${this._showRestoredChanged}">
|
||||
<paper-checkbox
|
||||
.checked=${this._showUnavailable}
|
||||
slot="item-icon"
|
||||
></paper-checkbox>
|
||||
${this.hass!.localize(
|
||||
"ui.panel.config.entities.picker.filter.show_unavailable"
|
||||
)}
|
||||
</paper-icon-item>
|
||||
</paper-listbox>
|
||||
</paper-menu-button>
|
||||
`}
|
||||
</div>
|
||||
</ha-data-table>
|
||||
</div>
|
||||
</hass-tabs-subpage>
|
||||
<div class=${classMap({
|
||||
"search-toolbar": this.narrow,
|
||||
"table-header": !this.narrow,
|
||||
})} slot="header">
|
||||
${headerToolbar}
|
||||
</div>
|
||||
</ha-data-table>
|
||||
</hass-tabs-subpage-data-table>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -387,6 +424,10 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
this._showUnavailable = !this._showUnavailable;
|
||||
}
|
||||
|
||||
private _showReadOnlyChanged() {
|
||||
this._showReadOnly = !this._showReadOnly;
|
||||
}
|
||||
|
||||
private _handleSearchChange(ev: CustomEvent) {
|
||||
this._filter = ev.detail.value;
|
||||
}
|
||||
@ -479,15 +520,13 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
|
||||
private _openEditEntry(ev: CustomEvent): void {
|
||||
const entryId = (ev.detail as RowClickedEvent).id;
|
||||
const entityId = (ev.detail as RowClickedEvent).id;
|
||||
const entry = this._entities!.find(
|
||||
(entity) => entity.entity_id === entryId
|
||||
(entity) => entity.entity_id === entityId
|
||||
);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
this.getDialog = showEntityRegistryDetailDialog(this, {
|
||||
entry,
|
||||
entity_id: entityId,
|
||||
});
|
||||
}
|
||||
|
||||
@ -520,14 +559,13 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
font-weight: var(--paper-font-subhead_-_font-weight);
|
||||
line-height: var(--paper-font-subhead_-_line-height);
|
||||
}
|
||||
.intro {
|
||||
padding: 24px 16px;
|
||||
}
|
||||
.content {
|
||||
padding: 4px;
|
||||
}
|
||||
ha-data-table {
|
||||
width: 100%;
|
||||
--data-table-border-width: 0;
|
||||
}
|
||||
:host(:not([narrow])) ha-data-table {
|
||||
height: calc(100vh - 65px);
|
||||
display: block;
|
||||
}
|
||||
ha-switch {
|
||||
margin-top: 16px;
|
||||
@ -540,12 +578,26 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
search-input {
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
.search-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
margin-left: -24px;
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.selected-txt {
|
||||
font-weight: bold;
|
||||
margin-top: 38px;
|
||||
padding-left: 16px;
|
||||
}
|
||||
.table-header .selected-txt {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.search-toolbar .selected-txt {
|
||||
font-size: 16px;
|
||||
}
|
||||
.header-btns > mwc-button,
|
||||
.header-btns > paper-icon-button {
|
||||
margin: 8px;
|
||||
|
@ -3,7 +3,8 @@ import { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { DialogEntityRegistryDetail } from "./dialog-entity-registry-detail";
|
||||
|
||||
export interface EntityRegistryDetailDialogParams {
|
||||
entry: EntityRegistryEntry;
|
||||
entry?: EntityRegistryEntry;
|
||||
entity_id: string;
|
||||
}
|
||||
|
||||
export const loadEntityRegistryDetailDialog = () =>
|
||||
@ -21,12 +22,12 @@ const getDialog = () => {
|
||||
|
||||
export const showEntityRegistryDetailDialog = (
|
||||
element: HTMLElement,
|
||||
systemLogDetailParams: EntityRegistryDetailDialogParams
|
||||
entityDetailParams: EntityRegistryDetailDialogParams
|
||||
): (() => DialogEntityRegistryDetail | undefined) => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-entity-registry-detail",
|
||||
dialogImport: loadEntityRegistryDetailDialog,
|
||||
dialogParams: systemLogDetailParams,
|
||||
dialogParams: entityDetailParams,
|
||||
});
|
||||
return getDialog;
|
||||
};
|
||||
|
@ -74,7 +74,7 @@ class DialogPersonDetail extends LitElement {
|
||||
@closing="${this._close}"
|
||||
scrimClickAction=""
|
||||
escapeKeyAction=""
|
||||
.title=${title}
|
||||
.heading=${title}
|
||||
>
|
||||
<div>
|
||||
${this._error
|
||||
|
@ -160,6 +160,10 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
this._deviceEntityLookup,
|
||||
this._deviceRegistryEntries
|
||||
);
|
||||
const name = this.scene
|
||||
? computeStateName(this.scene)
|
||||
: this.hass.localize("ui.panel.config.scene.editor.default_name");
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
.hass=${this.hass}
|
||||
@ -191,6 +195,13 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
`
|
||||
: ""
|
||||
}
|
||||
${
|
||||
this.narrow
|
||||
? html`
|
||||
<span slot="header">${name}</span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
<div
|
||||
id="root"
|
||||
class="${classMap({
|
||||
@ -198,15 +209,13 @@ export class HaSceneEditor extends SubscribeMixin(LitElement) {
|
||||
})}"
|
||||
>
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<div slot="header">
|
||||
${
|
||||
this.scene
|
||||
? computeStateName(this.scene)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.scene.editor.default_name"
|
||||
)
|
||||
}
|
||||
</div>
|
||||
${
|
||||
!this.narrow
|
||||
? html`
|
||||
<span slot="header">${name}</span>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
<div slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.scene.editor.introduction"
|
||||
|
@ -29,6 +29,7 @@ import { HomeAssistant, Route } from "../../../types";
|
||||
import "../automation/action/ha-automation-action";
|
||||
import { computeObjectId } from "../../../common/entity/compute_object_id";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { HaDeviceAction } from "../automation/action/types/ha-automation-action-device_id";
|
||||
|
||||
export class HaScriptEditor extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
@ -62,7 +63,11 @@ export class HaScriptEditor extends LitElement {
|
||||
@click=${this._deleteConfirm}
|
||||
></paper-icon-button>
|
||||
`}
|
||||
|
||||
${this.narrow
|
||||
? html`
|
||||
<span slot="header">${this._config?.alias}</span>
|
||||
`
|
||||
: ""}
|
||||
<div class="content">
|
||||
${this._errors
|
||||
? html`
|
||||
@ -77,7 +82,11 @@ export class HaScriptEditor extends LitElement {
|
||||
${this._config
|
||||
? html`
|
||||
<ha-config-section .isWide=${this.isWide}>
|
||||
<span slot="header">${this._config.alias}</span>
|
||||
${!this.narrow
|
||||
? html`
|
||||
<span slot="header">${this._config.alias}</span>
|
||||
`
|
||||
: ""}
|
||||
<span slot="introduction">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.script.editor.introduction"
|
||||
@ -193,7 +202,7 @@ export class HaScriptEditor extends LitElement {
|
||||
this._dirty = initData ? true : false;
|
||||
this._config = {
|
||||
alias: this.hass.localize("ui.panel.config.script.editor.default_name"),
|
||||
sequence: [{ service: "" }],
|
||||
sequence: [{ ...HaDeviceAction.defaultConfig }],
|
||||
...initData,
|
||||
};
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import {
|
||||
ZoneMutableParams,
|
||||
passiveRadiusColor,
|
||||
defaultRadiusColor,
|
||||
getZoneEditorInitData,
|
||||
} from "../../../data/zone";
|
||||
import { addDistanceToCoord } from "../../../common/location/add_distance_to_coord";
|
||||
|
||||
@ -47,15 +48,20 @@ class DialogZoneDetail extends LitElement {
|
||||
this._passive = this._params.entry.passive || false;
|
||||
this._radius = this._params.entry.radius || 100;
|
||||
} else {
|
||||
const movedHomeLocation = addDistanceToCoord(
|
||||
[this.hass.config.latitude, this.hass.config.longitude],
|
||||
500,
|
||||
500
|
||||
);
|
||||
this._name = "";
|
||||
this._icon = "mdi:map-marker";
|
||||
this._latitude = movedHomeLocation[0];
|
||||
this._longitude = movedHomeLocation[1];
|
||||
const initConfig = getZoneEditorInitData();
|
||||
let movedHomeLocation;
|
||||
if (!initConfig?.latitude || !initConfig?.longitude) {
|
||||
movedHomeLocation = addDistanceToCoord(
|
||||
[this.hass.config.latitude, this.hass.config.longitude],
|
||||
Math.random() * 500 * (Math.random() < 0.5 ? -1 : 1),
|
||||
Math.random() * 500 * (Math.random() < 0.5 ? -1 : 1)
|
||||
);
|
||||
}
|
||||
this._latitude = initConfig?.latitude || movedHomeLocation[0];
|
||||
this._longitude = initConfig?.longitude || movedHomeLocation[1];
|
||||
this._name = initConfig?.name || "";
|
||||
this._icon = initConfig?.icon || "mdi:map-marker";
|
||||
|
||||
this._passive = false;
|
||||
this._radius = 100;
|
||||
}
|
||||
@ -94,7 +100,7 @@ class DialogZoneDetail extends LitElement {
|
||||
@closing="${this._close}"
|
||||
scrimClickAction=""
|
||||
escapeKeyAction=""
|
||||
.title=${title}
|
||||
.heading=${title}
|
||||
>
|
||||
<div>
|
||||
${this._error
|
||||
|
@ -46,6 +46,10 @@ import memoizeOne from "memoize-one";
|
||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||
import { subscribeEntityRegistry } from "../../../data/entity_registry";
|
||||
import { configSections } from "../ha-panel-config";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { saveCoreConfig } from "../../../data/core";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
|
||||
|
||||
@customElement("ha-config-zone")
|
||||
export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
@ -56,6 +60,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
@property() private _storageItems?: Zone[];
|
||||
@property() private _stateItems?: HassEntity[];
|
||||
@property() private _activeEntry: string = "";
|
||||
@property() private _canEditCore = false;
|
||||
@query("ha-locations-editor") private _map?: HaLocationsEditor;
|
||||
private _regEntities: string[] = [];
|
||||
|
||||
@ -75,14 +80,17 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
: state.attributes.passive
|
||||
? passiveRadiusColor
|
||||
: defaultRadiusColor,
|
||||
editable: false,
|
||||
location_editable:
|
||||
state.entity_id === "zone.home" && this._canEditCore,
|
||||
radius_editable: false,
|
||||
};
|
||||
});
|
||||
const storageLocations: MarkerLocation[] = storageItems.map((zone) => {
|
||||
return {
|
||||
...zone,
|
||||
radius_color: zone.passive ? passiveRadiusColor : defaultRadiusColor,
|
||||
editable: true,
|
||||
location_editable: true,
|
||||
radius_editable: true,
|
||||
};
|
||||
});
|
||||
return storageLocations.concat(stateLocations);
|
||||
@ -165,12 +173,23 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
<paper-icon-button
|
||||
.entityId=${state.entity_id}
|
||||
icon="hass:pencil"
|
||||
disabled
|
||||
@click=${this._openCoreConfig}
|
||||
disabled=${ifDefined(
|
||||
state.entity_id === "zone.home" &&
|
||||
this.narrow &&
|
||||
this._canEditCore
|
||||
? undefined
|
||||
: true
|
||||
)}
|
||||
></paper-icon-button>
|
||||
<paper-tooltip position="left">
|
||||
${state.entity_id === "zone.home"
|
||||
? this.hass.localize(
|
||||
"ui.panel.config.zone.edit_home_zone"
|
||||
`ui.panel.config.zone.${
|
||||
this.narrow
|
||||
? "edit_home_zone_narrow"
|
||||
: "edit_home_zone"
|
||||
}`
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.config.zone.configured_in_yaml"
|
||||
@ -233,7 +252,14 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this._canEditCore =
|
||||
Boolean(this.hass.user?.is_admin) &&
|
||||
["storage", "default"].includes(this.hass.config.config_source);
|
||||
this._fetchData();
|
||||
if (this.route.path === "/new") {
|
||||
navigate(this, "/config/zone", true);
|
||||
this._createZone();
|
||||
}
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
@ -283,8 +309,15 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private _locationUpdated(ev: CustomEvent) {
|
||||
private async _locationUpdated(ev: CustomEvent) {
|
||||
this._activeEntry = ev.detail.id;
|
||||
if (ev.detail.id === "zone.home" && this._canEditCore) {
|
||||
await saveCoreConfig(this.hass, {
|
||||
latitude: ev.detail.location[0],
|
||||
longitude: ev.detail.location[1],
|
||||
});
|
||||
return;
|
||||
}
|
||||
const entry = this._storageItems!.find((item) => item.id === ev.detail.id);
|
||||
if (!entry) {
|
||||
return;
|
||||
@ -314,7 +347,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
this._openDialog();
|
||||
}
|
||||
|
||||
private _itemClicked(ev: MouseEvent) {
|
||||
private _itemClicked(ev: Event) {
|
||||
if (this.narrow) {
|
||||
this._openEditEntry(ev);
|
||||
return;
|
||||
@ -323,7 +356,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
this._zoomZone(entry.id);
|
||||
}
|
||||
|
||||
private _stateItemClicked(ev: MouseEvent) {
|
||||
private _stateItemClicked(ev: Event) {
|
||||
const entityId = (ev.currentTarget! as HTMLElement).getAttribute(
|
||||
"data-id"
|
||||
)!;
|
||||
@ -334,11 +367,29 @@ export class HaConfigZone extends SubscribeMixin(LitElement) {
|
||||
this._map?.fitMarker(id);
|
||||
}
|
||||
|
||||
private _openEditEntry(ev: MouseEvent) {
|
||||
private _openEditEntry(ev: Event) {
|
||||
const entry: Zone = (ev.currentTarget! as any).entry;
|
||||
this._openDialog(entry);
|
||||
}
|
||||
|
||||
private async _openCoreConfig(ev: Event) {
|
||||
const entityId: string = (ev.currentTarget! as any).entityId;
|
||||
if (entityId !== "zone.home" || !this.narrow || !this._canEditCore) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!(await showConfirmationDialog(this, {
|
||||
title: this.hass.localize("ui.panel.config.zone.go_to_core_config"),
|
||||
text: this.hass.localize("ui.panel.config.zone.home_zone_core_config"),
|
||||
confirmText: this.hass!.localize("ui.common.yes"),
|
||||
dismissText: this.hass!.localize("ui.common.no"),
|
||||
}))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
navigate(this, "/config/core");
|
||||
}
|
||||
|
||||
private async _createEntry(values: ZoneMutableParams) {
|
||||
const created = await createZone(this.hass!, values);
|
||||
this._storageItems = this._storageItems!.concat(
|
||||
|
@ -357,16 +357,22 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
||||
|
||||
for (i = 0, keys = Object.keys(entity.attributes); i < keys.length; i++) {
|
||||
key = keys[i];
|
||||
value = entity.attributes[key];
|
||||
if (!Array.isArray(value) && value instanceof Object) {
|
||||
value = JSON.stringify(value, null, " ");
|
||||
}
|
||||
output += key + ": " + value + "\n";
|
||||
value = this.formatAttributeValue(entity.attributes[key]);
|
||||
output += `${key}: ${value}\n`;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
formatAttributeValue(value) {
|
||||
if (
|
||||
(Array.isArray(value) && value.some((val) => val instanceof Object)) ||
|
||||
(!Array.isArray(value) && value instanceof Object)
|
||||
) {
|
||||
return `\n${safeDump(value)}`;
|
||||
}
|
||||
return Array.isArray(value) ? value.join(", ") : value;
|
||||
}
|
||||
|
||||
_computeParsedStateAttributes(stateAttributes) {
|
||||
try {
|
||||
return stateAttributes.trim() ? safeLoad(stateAttributes) : {};
|
||||
|
@ -51,6 +51,7 @@ class HaPanelHistory extends LocalizeMixin(PolymerElement) {
|
||||
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
259
src/panels/lovelace/cards/hui-button-card.ts
Normal file
259
src/panels/lovelace/cards/hui-button-card.ts
Normal file
@ -0,0 +1,259 @@
|
||||
import {
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
CSSResult,
|
||||
css,
|
||||
customElement,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "@material/mwc-ripple";
|
||||
|
||||
import "../../../components/ha-card";
|
||||
import "../components/hui-warning";
|
||||
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
|
||||
import { HomeAssistant, LightEntity } from "../../../types";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||
import { ButtonCardConfig } from "./types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { hasAction } from "../common/has-action";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { computeActiveState } from "../../../common/entity/compute_active_state";
|
||||
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
||||
|
||||
@customElement("hui-button-card")
|
||||
export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
||||
await import(
|
||||
/* webpackChunkName: "hui-button-card-editor" */ "../editor/config-elements/hui-button-card-editor"
|
||||
);
|
||||
return document.createElement("hui-button-card-editor");
|
||||
}
|
||||
|
||||
public static getStubConfig(): object {
|
||||
return {
|
||||
tap_action: { action: "toggle" },
|
||||
hold_action: { action: "more-info" },
|
||||
show_icon: true,
|
||||
show_name: true,
|
||||
state_color: true,
|
||||
};
|
||||
}
|
||||
|
||||
@property() public hass?: HomeAssistant;
|
||||
|
||||
@property() private _config?: ButtonCardConfig;
|
||||
|
||||
public getCardSize(): number {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public setConfig(config: ButtonCardConfig): void {
|
||||
if (config.entity && !isValidEntityId(config.entity)) {
|
||||
throw new Error("Invalid Entity");
|
||||
}
|
||||
|
||||
this._config = {
|
||||
theme: "default",
|
||||
hold_action: { action: "more-info" },
|
||||
double_tap_action: { action: "none" },
|
||||
show_icon: true,
|
||||
show_name: true,
|
||||
...config,
|
||||
};
|
||||
|
||||
if (config.entity && DOMAINS_TOGGLE.has(computeDomain(config.entity))) {
|
||||
this._config = {
|
||||
tap_action: {
|
||||
action: "toggle",
|
||||
},
|
||||
...this._config,
|
||||
};
|
||||
} else {
|
||||
this._config = {
|
||||
tap_action: {
|
||||
action: "more-info",
|
||||
},
|
||||
...this._config,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
if (changedProps.has("_config")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (
|
||||
!oldHass ||
|
||||
oldHass.themes !== this.hass!.themes ||
|
||||
oldHass.language !== this.hass!.language
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
Boolean(this._config!.entity) &&
|
||||
oldHass.states[this._config!.entity!] !==
|
||||
this.hass!.states[this._config!.entity!]
|
||||
);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._config || !this.hass) {
|
||||
return html``;
|
||||
}
|
||||
const stateObj = this._config.entity
|
||||
? this.hass.states[this._config.entity]
|
||||
: undefined;
|
||||
|
||||
if (this._config.entity && !stateObj) {
|
||||
return html`
|
||||
<hui-warning
|
||||
>${this.hass.localize(
|
||||
"ui.panel.lovelace.warning.entity_not_found",
|
||||
"entity",
|
||||
this._config.entity
|
||||
)}</hui-warning
|
||||
>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-card
|
||||
@action=${this._handleAction}
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: hasAction(this._config!.hold_action),
|
||||
hasDoubleClick: hasAction(this._config!.double_tap_action),
|
||||
})}
|
||||
tabindex=${ifDefined(
|
||||
hasAction(this._config.tap_action) ? "0" : undefined
|
||||
)}
|
||||
>
|
||||
${this._config.show_icon
|
||||
? html`
|
||||
<ha-icon
|
||||
data-domain=${ifDefined(
|
||||
this._config.state_color && stateObj
|
||||
? computeStateDomain(stateObj)
|
||||
: undefined
|
||||
)}
|
||||
data-state=${ifDefined(
|
||||
stateObj ? computeActiveState(stateObj) : undefined
|
||||
)}
|
||||
.icon=${this._config.icon ||
|
||||
(stateObj ? stateIcon(stateObj) : "")}
|
||||
style=${styleMap({
|
||||
filter: stateObj ? this._computeBrightness(stateObj) : "",
|
||||
color: stateObj ? this._computeColor(stateObj) : "",
|
||||
height: this._config.icon_height
|
||||
? this._config.icon_height
|
||||
: "auto",
|
||||
})}
|
||||
></ha-icon>
|
||||
`
|
||||
: ""}
|
||||
${this._config.show_name
|
||||
? html`
|
||||
<span>
|
||||
${this._config.name ||
|
||||
(stateObj ? computeStateName(stateObj) : "")}
|
||||
</span>
|
||||
`
|
||||
: ""}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
super.updated(changedProps);
|
||||
if (!this._config || !this.hass) {
|
||||
return;
|
||||
}
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
const oldConfig = changedProps.get("_config") as
|
||||
| ButtonCardConfig
|
||||
| undefined;
|
||||
|
||||
if (
|
||||
!oldHass ||
|
||||
!oldConfig ||
|
||||
oldHass.themes !== this.hass.themes ||
|
||||
oldConfig.theme !== this._config.theme
|
||||
) {
|
||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
ha-card {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 4% 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
ha-card:focus {
|
||||
outline: none;
|
||||
background: var(--divider-color);
|
||||
}
|
||||
|
||||
ha-icon {
|
||||
width: 40%;
|
||||
height: auto;
|
||||
color: var(--paper-item-icon-color, #44739e);
|
||||
}
|
||||
|
||||
${iconColorCSS}
|
||||
`;
|
||||
}
|
||||
|
||||
private _computeBrightness(stateObj: HassEntity | LightEntity): string {
|
||||
if (!stateObj.attributes.brightness || !this._config?.state_color) {
|
||||
return "";
|
||||
}
|
||||
const brightness = stateObj.attributes.brightness;
|
||||
return `brightness(${(brightness + 245) / 5}%)`;
|
||||
}
|
||||
|
||||
private _computeColor(stateObj: HassEntity | LightEntity): string {
|
||||
if (!stateObj.attributes.hs_color || !this._config?.state_color) {
|
||||
return "";
|
||||
}
|
||||
const [hue, sat] = stateObj.attributes.hs_color;
|
||||
if (sat <= 10) {
|
||||
return "";
|
||||
}
|
||||
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
||||
}
|
||||
|
||||
private _handleAction(ev: ActionHandlerEvent) {
|
||||
handleAction(this, this.hass!, this._config!, ev.detail.action!);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-button-card": HuiButtonCard;
|
||||
}
|
||||
}
|
@ -1,246 +1,9 @@
|
||||
import {
|
||||
html,
|
||||
LitElement,
|
||||
PropertyValues,
|
||||
TemplateResult,
|
||||
CSSResult,
|
||||
css,
|
||||
customElement,
|
||||
property,
|
||||
} from "lit-element";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "@material/mwc-ripple";
|
||||
import { customElement } from "lit-element";
|
||||
|
||||
import "../../../components/ha-card";
|
||||
import "../components/hui-warning";
|
||||
|
||||
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
|
||||
import { stateIcon } from "../../../common/entity/state_icon";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
|
||||
import { HomeAssistant, LightEntity } from "../../../types";
|
||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||
import { EntityButtonCardConfig } from "./types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { hasAction } from "../common/has-action";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||
import { computeActiveState } from "../../../common/entity/compute_active_state";
|
||||
import { iconColorCSS } from "../../../common/style/icon_color_css";
|
||||
import { HuiButtonCard } from "./hui-button-card";
|
||||
|
||||
@customElement("hui-entity-button-card")
|
||||
class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
||||
public static async getConfigElement(): Promise<LovelaceCardEditor> {
|
||||
await import(
|
||||
/* webpackChunkName: "hui-entity-button-card-editor" */ "../editor/config-elements/hui-entity-button-card-editor"
|
||||
);
|
||||
return document.createElement("hui-entity-button-card-editor");
|
||||
}
|
||||
|
||||
public static getStubConfig(): object {
|
||||
return {
|
||||
tap_action: { action: "toggle" },
|
||||
hold_action: { action: "more-info" },
|
||||
show_icon: true,
|
||||
show_name: true,
|
||||
};
|
||||
}
|
||||
|
||||
@property() public hass?: HomeAssistant;
|
||||
|
||||
@property() private _config?: EntityButtonCardConfig;
|
||||
|
||||
public getCardSize(): number {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public setConfig(config: EntityButtonCardConfig): void {
|
||||
if (!isValidEntityId(config.entity)) {
|
||||
throw new Error("Invalid Entity");
|
||||
}
|
||||
|
||||
this._config = {
|
||||
theme: "default",
|
||||
hold_action: { action: "more-info" },
|
||||
double_tap_action: { action: "none" },
|
||||
show_icon: true,
|
||||
show_name: true,
|
||||
...config,
|
||||
};
|
||||
|
||||
if (DOMAINS_TOGGLE.has(computeDomain(config.entity))) {
|
||||
this._config = {
|
||||
tap_action: {
|
||||
action: "toggle",
|
||||
},
|
||||
...this._config,
|
||||
};
|
||||
} else {
|
||||
this._config = {
|
||||
tap_action: {
|
||||
action: "more-info",
|
||||
},
|
||||
...this._config,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
if (changedProps.has("_config")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
|
||||
if (
|
||||
!oldHass ||
|
||||
oldHass.themes !== this.hass!.themes ||
|
||||
oldHass.language !== this.hass!.language
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
oldHass.states[this._config!.entity] !==
|
||||
this.hass!.states[this._config!.entity]
|
||||
);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._config || !this.hass) {
|
||||
return html``;
|
||||
}
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
|
||||
if (!stateObj) {
|
||||
return html`
|
||||
<hui-warning
|
||||
>${this.hass.localize(
|
||||
"ui.panel.lovelace.warning.entity_not_found",
|
||||
"entity",
|
||||
this._config.entity
|
||||
)}</hui-warning
|
||||
>
|
||||
`;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-card
|
||||
@action=${this._handleAction}
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: hasAction(this._config!.hold_action),
|
||||
hasDoubleClick: hasAction(this._config!.double_tap_action),
|
||||
})}
|
||||
tabindex=${ifDefined(
|
||||
hasAction(this._config.tap_action) ||
|
||||
this._config.tap_action === undefined
|
||||
? "0"
|
||||
: undefined
|
||||
)}
|
||||
>
|
||||
${this._config.show_icon
|
||||
? html`
|
||||
<ha-icon
|
||||
data-domain=${computeStateDomain(stateObj)}
|
||||
data-state=${computeActiveState(stateObj)}
|
||||
.icon=${this._config.icon || stateIcon(stateObj)}
|
||||
style=${styleMap({
|
||||
filter: this._computeBrightness(stateObj),
|
||||
color: this._computeColor(stateObj),
|
||||
height: this._config.icon_height
|
||||
? this._config.icon_height
|
||||
: "auto",
|
||||
})}
|
||||
></ha-icon>
|
||||
`
|
||||
: ""}
|
||||
${this._config.show_name
|
||||
? html`
|
||||
<span>
|
||||
${this._config.name || computeStateName(stateObj)}
|
||||
</span>
|
||||
`
|
||||
: ""}
|
||||
<mwc-ripple></mwc-ripple>
|
||||
</ha-card>
|
||||
`;
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
super.updated(changedProps);
|
||||
if (!this._config || !this.hass) {
|
||||
return;
|
||||
}
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
const oldConfig = changedProps.get("_config") as
|
||||
| EntityButtonCardConfig
|
||||
| undefined;
|
||||
|
||||
if (
|
||||
!oldHass ||
|
||||
!oldConfig ||
|
||||
oldHass.themes !== this.hass.themes ||
|
||||
oldConfig.theme !== this._config.theme
|
||||
) {
|
||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
ha-card {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
padding: 4% 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
ha-card:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
ha-icon {
|
||||
width: 40%;
|
||||
height: auto;
|
||||
color: var(--paper-item-icon-color, #44739e);
|
||||
}
|
||||
|
||||
${iconColorCSS}
|
||||
`;
|
||||
}
|
||||
|
||||
private _computeBrightness(stateObj: HassEntity | LightEntity): string {
|
||||
if (!stateObj.attributes.brightness) {
|
||||
return "";
|
||||
}
|
||||
const brightness = stateObj.attributes.brightness;
|
||||
return `brightness(${(brightness + 245) / 5}%)`;
|
||||
}
|
||||
|
||||
private _computeColor(stateObj: HassEntity | LightEntity): string {
|
||||
if (!stateObj.attributes.hs_color) {
|
||||
return "";
|
||||
}
|
||||
const [hue, sat] = stateObj.attributes.hs_color;
|
||||
if (sat <= 10) {
|
||||
return "";
|
||||
}
|
||||
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
||||
}
|
||||
|
||||
private _handleAction(ev: ActionHandlerEvent) {
|
||||
handleAction(this, this.hass!, this._config!, ev.detail.action!);
|
||||
}
|
||||
}
|
||||
class HuiEntityButtonCard extends HuiButtonCard {}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
|
@ -59,7 +59,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
public setConfig(config: GlanceCardConfig): void {
|
||||
this._config = { theme: "default", ...config };
|
||||
this._config = { theme: "default", state_color: true, ...config };
|
||||
const entities = processConfigEntities<GlanceConfigEntity>(config.entities);
|
||||
|
||||
for (const entity of entities) {
|
||||
@ -237,7 +237,9 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
||||
.stateObj=${stateObj}
|
||||
.overrideIcon=${entityConf.icon}
|
||||
.overrideImage=${entityConf.image}
|
||||
stateColor
|
||||
.stateColor=${(entityConf.state_color === false ||
|
||||
entityConf.state_color) ??
|
||||
this._config!.state_color}
|
||||
></state-badge>
|
||||
`
|
||||
: ""}
|
||||
|
@ -90,7 +90,7 @@ const calcPoints = (
|
||||
let last = [average(first), lastValue(first)];
|
||||
|
||||
const getCoords = (item, i, offset = 0, depth = 1) => {
|
||||
if (depth > 1) {
|
||||
if (depth > 1 && item) {
|
||||
return item.forEach((subItem, index) =>
|
||||
getCoords(subItem, i, index, depth - 1)
|
||||
);
|
||||
@ -255,11 +255,11 @@ class HuiSensorCard extends LitElement implements LovelaceCard {
|
||||
<rect height="100%" width="100%" id="fill-rect" fill="var(--accent-color)" mask="url(#fill)"></rect>
|
||||
<mask id="line">
|
||||
<path
|
||||
fill="none"
|
||||
fill="none"
|
||||
stroke="var(--accent-color)"
|
||||
stroke-width="5"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-linejoin="round"
|
||||
d=${this._history}
|
||||
></path>
|
||||
</mask>
|
||||
@ -428,17 +428,12 @@ class HuiSensorCard extends LitElement implements LovelaceCard {
|
||||
|
||||
.icon {
|
||||
color: var(--paper-item-icon-color, #44739e);
|
||||
display: inline-block;
|
||||
flex: 0 0 40px;
|
||||
line-height: 40px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.info {
|
||||
flex-wrap: wrap;
|
||||
margin: 16px;
|
||||
margin: 0 16px 16px;
|
||||
}
|
||||
|
||||
#value {
|
||||
|
@ -269,7 +269,11 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
applyThemesOnElement(this, this.hass.themes, this._config.theme);
|
||||
}
|
||||
|
||||
this._setTemp = this._getSetTemp(this.hass!.states[this._config!.entity]);
|
||||
const stateObj = this.hass!.states[this._config!.entity];
|
||||
if (!stateObj) {
|
||||
return;
|
||||
}
|
||||
this._setTemp = this._getSetTemp(stateObj);
|
||||
this.rescale_svg();
|
||||
}
|
||||
|
||||
|
@ -47,8 +47,8 @@ export interface EntitiesCardConfig extends LovelaceCardConfig {
|
||||
state_color?: boolean;
|
||||
}
|
||||
|
||||
export interface EntityButtonCardConfig extends LovelaceCardConfig {
|
||||
entity: string;
|
||||
export interface ButtonCardConfig extends LovelaceCardConfig {
|
||||
entity?: string;
|
||||
name?: string;
|
||||
show_name?: boolean;
|
||||
icon?: string;
|
||||
@ -57,6 +57,7 @@ export interface EntityButtonCardConfig extends LovelaceCardConfig {
|
||||
tap_action?: ActionConfig;
|
||||
hold_action?: ActionConfig;
|
||||
double_tap_action?: ActionConfig;
|
||||
state_color?: boolean;
|
||||
}
|
||||
|
||||
export interface EntityFilterCardConfig extends LovelaceCardConfig {
|
||||
@ -102,6 +103,7 @@ export interface GlanceConfigEntity extends ConfigEntity {
|
||||
show_last_changed?: boolean;
|
||||
image?: string;
|
||||
show_state?: boolean;
|
||||
state_color?: boolean;
|
||||
}
|
||||
|
||||
export interface GlanceCardConfig extends LovelaceCardConfig {
|
||||
@ -112,6 +114,7 @@ export interface GlanceCardConfig extends LovelaceCardConfig {
|
||||
theme?: string;
|
||||
entities: ConfigEntity[];
|
||||
columns?: number;
|
||||
state_color?: boolean;
|
||||
}
|
||||
|
||||
export interface IframeCardConfig extends LovelaceCardConfig {
|
||||
|
@ -1,10 +1,19 @@
|
||||
import "../badges/hui-entity-filter-badge";
|
||||
import "../badges/hui-state-label-badge";
|
||||
|
||||
import { LovelaceBadgeConfig } from "../../../data/lovelace";
|
||||
import { createLovelaceElement } from "./create-element-base";
|
||||
|
||||
const BADGE_TYPES = new Set(["entity-filter", "error", "state-label"]);
|
||||
const ALWAYS_LOADED_TYPES = new Set(["error", "state-label"]);
|
||||
const LAZY_LOAD_TYPES = {
|
||||
"entity-filter": () => import("../badges/hui-entity-filter-badge"),
|
||||
};
|
||||
|
||||
export const createBadgeElement = (config: LovelaceBadgeConfig) =>
|
||||
createLovelaceElement("badge", config, BADGE_TYPES, undefined, "state-label");
|
||||
createLovelaceElement(
|
||||
"badge",
|
||||
config,
|
||||
ALWAYS_LOADED_TYPES,
|
||||
LAZY_LOAD_TYPES,
|
||||
undefined,
|
||||
"state-label"
|
||||
);
|
||||
|
@ -1,57 +1,56 @@
|
||||
import "../cards/hui-alarm-panel-card";
|
||||
import "../cards/hui-conditional-card";
|
||||
import "../cards/hui-entities-card";
|
||||
import "../cards/hui-button-card";
|
||||
import "../cards/hui-entity-button-card";
|
||||
import "../cards/hui-entity-filter-card";
|
||||
import "../cards/hui-glance-card";
|
||||
import "../cards/hui-history-graph-card";
|
||||
import "../cards/hui-horizontal-stack-card";
|
||||
import "../cards/hui-iframe-card";
|
||||
import "../cards/hui-light-card";
|
||||
import "../cards/hui-map-card";
|
||||
import "../cards/hui-markdown-card";
|
||||
import "../cards/hui-media-control-card";
|
||||
import "../cards/hui-picture-card";
|
||||
import "../cards/hui-picture-elements-card";
|
||||
import "../cards/hui-picture-entity-card";
|
||||
import "../cards/hui-picture-glance-card";
|
||||
import "../cards/hui-plant-status-card";
|
||||
import "../cards/hui-sensor-card";
|
||||
import "../cards/hui-vertical-stack-card";
|
||||
import "../cards/hui-shopping-list-card";
|
||||
import "../cards/hui-thermostat-card";
|
||||
import "../cards/hui-vertical-stack-card";
|
||||
import "../cards/hui-weather-forecast-card";
|
||||
import "../cards/hui-gauge-card";
|
||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||
import { createLovelaceElement } from "./create-element-base";
|
||||
|
||||
const CARD_TYPES = new Set([
|
||||
"alarm-panel",
|
||||
"conditional",
|
||||
const ALWAYS_LOADED_TYPES = new Set([
|
||||
"entities",
|
||||
"button",
|
||||
"entity-button",
|
||||
"entity-filter",
|
||||
"error",
|
||||
"gauge",
|
||||
"glance",
|
||||
"history-graph",
|
||||
"horizontal-stack",
|
||||
"iframe",
|
||||
"light",
|
||||
"map",
|
||||
"markdown",
|
||||
"media-control",
|
||||
"picture",
|
||||
"picture-elements",
|
||||
"picture-entity",
|
||||
"picture-glance",
|
||||
"plant-status",
|
||||
"sensor",
|
||||
"shopping-list",
|
||||
"thermostat",
|
||||
"vertical-stack",
|
||||
"weather-forecast",
|
||||
]);
|
||||
|
||||
const LAZY_LOAD_TYPES = {
|
||||
"alarm-panel": () => import("../cards/hui-alarm-panel-card"),
|
||||
"entity-filter": () => import("../cards/hui-entity-filter-card"),
|
||||
"picture-elements": () => import("../cards/hui-picture-elements-card"),
|
||||
"picture-entity": () => import("../cards/hui-picture-entity-card"),
|
||||
"picture-glance": () => import("../cards/hui-picture-glance-card"),
|
||||
"plant-status": () => import("../cards/hui-plant-status-card"),
|
||||
"shopping-list": () => import("../cards/hui-shopping-list-card"),
|
||||
conditional: () => import("../cards/hui-conditional-card"),
|
||||
gauge: () => import("../cards/hui-gauge-card"),
|
||||
iframe: () => import("../cards/hui-iframe-card"),
|
||||
map: () => import("../cards/hui-map-card"),
|
||||
markdown: () => import("../cards/hui-markdown-card"),
|
||||
picture: () => import("../cards/hui-picture-card"),
|
||||
};
|
||||
|
||||
export const createCardElement = (config: LovelaceCardConfig) =>
|
||||
createLovelaceElement("card", config, CARD_TYPES);
|
||||
createLovelaceElement(
|
||||
"card",
|
||||
config,
|
||||
ALWAYS_LOADED_TYPES,
|
||||
LAZY_LOAD_TYPES,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
@ -50,10 +50,36 @@ const _createErrorElement = <T extends keyof CreateElementConfigTypes>(
|
||||
config: CreateElementConfigTypes[T]["config"]
|
||||
): HuiErrorCard => createErrorCardElement(createErrorCardConfig(error, config));
|
||||
|
||||
const _maybeCreate = <T extends keyof CreateElementConfigTypes>(
|
||||
tag: string,
|
||||
config: CreateElementConfigTypes[T]["config"]
|
||||
) => {
|
||||
if (customElements.get(tag)) {
|
||||
return _createElement(tag, config);
|
||||
}
|
||||
|
||||
const element = _createErrorElement(
|
||||
`Custom element doesn't exist: ${tag}.`,
|
||||
config
|
||||
);
|
||||
element.style.display = "None";
|
||||
const timer = window.setTimeout(() => {
|
||||
element.style.display = "";
|
||||
}, TIMEOUT);
|
||||
|
||||
customElements.whenDefined(tag).then(() => {
|
||||
clearTimeout(timer);
|
||||
fireEvent(element, "ll-rebuild");
|
||||
});
|
||||
|
||||
return element;
|
||||
};
|
||||
|
||||
export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||
tagSuffix: T,
|
||||
config: CreateElementConfigTypes[T]["config"],
|
||||
elementTypes: Set<string>,
|
||||
alwaysLoadTypes?: Set<string>,
|
||||
lazyLoadTypes?: { [domain: string]: () => unknown },
|
||||
// Allow looking at "entity" in config and mapping that to a type
|
||||
domainTypes?: { _domain_not_found: string; [domain: string]: string },
|
||||
// Default type if no type given. If given, entity types will not work.
|
||||
@ -73,43 +99,35 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||
}
|
||||
|
||||
if (config.type && config.type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
||||
const tag = config.type.substr(CUSTOM_TYPE_PREFIX.length);
|
||||
|
||||
if (customElements.get(tag)) {
|
||||
return _createElement(tag, config);
|
||||
}
|
||||
const element = _createErrorElement(
|
||||
`Custom element doesn't exist: ${tag}.`,
|
||||
config
|
||||
);
|
||||
element.style.display = "None";
|
||||
const timer = window.setTimeout(() => {
|
||||
element.style.display = "";
|
||||
}, TIMEOUT);
|
||||
|
||||
customElements.whenDefined(tag).then(() => {
|
||||
clearTimeout(timer);
|
||||
fireEvent(element, "ll-rebuild");
|
||||
});
|
||||
|
||||
return element;
|
||||
return _maybeCreate(config.type.substr(CUSTOM_TYPE_PREFIX.length), config);
|
||||
}
|
||||
|
||||
let type: string | undefined;
|
||||
|
||||
// config.type has priority over config.entity, but defaultType has not.
|
||||
// @ts-ignore
|
||||
if (domainTypes && !config.type && config.entity) {
|
||||
// @ts-ignore
|
||||
const domain = config.entity.split(".", 1)[0];
|
||||
return _createElement(
|
||||
`hui-${domainTypes![domain] ||
|
||||
domainTypes!._domain_not_found}-entity-${tagSuffix}`,
|
||||
config
|
||||
);
|
||||
type = `${domainTypes![domain] || domainTypes!._domain_not_found}-entity`;
|
||||
} else {
|
||||
type = config.type || defaultType;
|
||||
}
|
||||
|
||||
const type = config.type || defaultType;
|
||||
if (type === undefined) {
|
||||
return _createErrorElement(`No type specified`, config);
|
||||
}
|
||||
|
||||
return type !== undefined && elementTypes.has(type)
|
||||
? _createElement(`hui-${type}-${tagSuffix}`, config)
|
||||
: _createErrorElement(`Unknown type encountered: ${type}.`, config);
|
||||
const tag = `hui-${type}-${tagSuffix}`;
|
||||
|
||||
if (lazyLoadTypes && type in lazyLoadTypes) {
|
||||
lazyLoadTypes[type]();
|
||||
return _maybeCreate(tag, config);
|
||||
}
|
||||
|
||||
if (alwaysLoadTypes && alwaysLoadTypes.has(type)) {
|
||||
return _createElement(tag, config);
|
||||
}
|
||||
|
||||
return _createErrorElement(`Unknown type encountered: ${type}.`, config);
|
||||
};
|
||||
|
@ -1,9 +1,17 @@
|
||||
import "../header-footer/hui-picture-header-footer";
|
||||
import "../header-footer/hui-buttons-header-footer";
|
||||
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
|
||||
import { createLovelaceElement } from "./create-element-base";
|
||||
|
||||
const SPECIAL_TYPES = new Set(["picture", "buttons"]);
|
||||
const LAZY_LOAD_TYPES = {
|
||||
picture: () => import("../header-footer/hui-picture-header-footer"),
|
||||
buttons: () => import("../header-footer/hui-buttons-header-footer"),
|
||||
};
|
||||
|
||||
export const createHeaderFooterElement = (config: LovelaceHeaderFooterConfig) =>
|
||||
createLovelaceElement("header-footer", config, SPECIAL_TYPES);
|
||||
createLovelaceElement(
|
||||
"header-footer",
|
||||
config,
|
||||
undefined,
|
||||
LAZY_LOAD_TYPES,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
@ -9,7 +9,7 @@ import "../elements/hui-state-label-element";
|
||||
import { LovelaceElementConfig } from "../elements/types";
|
||||
import { createLovelaceElement } from "./create-element-base";
|
||||
|
||||
const ELEMENT_TYPES = new Set([
|
||||
const ALWAYS_LOADED_TYPES = new Set([
|
||||
"conditional",
|
||||
"icon",
|
||||
"image",
|
||||
@ -20,4 +20,4 @@ const ELEMENT_TYPES = new Set([
|
||||
]);
|
||||
|
||||
export const createHuiElement = (config: LovelaceElementConfig) =>
|
||||
createLovelaceElement("element", config, ELEMENT_TYPES);
|
||||
createLovelaceElement("element", config, ALWAYS_LOADED_TYPES);
|
||||
|
@ -1,36 +1,41 @@
|
||||
import "../entity-rows/hui-climate-entity-row";
|
||||
import "../entity-rows/hui-cover-entity-row";
|
||||
import "../entity-rows/hui-group-entity-row";
|
||||
import "../entity-rows/hui-input-datetime-entity-row";
|
||||
import "../entity-rows/hui-input-number-entity-row";
|
||||
import "../entity-rows/hui-input-select-entity-row";
|
||||
import "../entity-rows/hui-input-text-entity-row";
|
||||
import "../entity-rows/hui-lock-entity-row";
|
||||
import "../entity-rows/hui-media-player-entity-row";
|
||||
import "../entity-rows/hui-scene-entity-row";
|
||||
import "../entity-rows/hui-script-entity-row";
|
||||
import "../entity-rows/hui-sensor-entity-row";
|
||||
import "../entity-rows/hui-text-entity-row";
|
||||
import "../entity-rows/hui-timer-entity-row";
|
||||
import "../entity-rows/hui-toggle-entity-row";
|
||||
import "../special-rows/hui-call-service-row";
|
||||
import "../special-rows/hui-conditional-row";
|
||||
import "../special-rows/hui-divider-row";
|
||||
import "../special-rows/hui-section-row";
|
||||
import "../special-rows/hui-weblink-row";
|
||||
import "../special-rows/hui-cast-row";
|
||||
import { EntityConfig } from "../entity-rows/types";
|
||||
import { createLovelaceElement } from "./create-element-base";
|
||||
|
||||
const SPECIAL_TYPES = new Set([
|
||||
const ALWAYS_LOADED_TYPES = new Set([
|
||||
"media-player-entity",
|
||||
"scene-entity",
|
||||
"script-entity",
|
||||
"sensor-entity",
|
||||
"text-entity",
|
||||
"toggle-entity",
|
||||
"call-service",
|
||||
"cast",
|
||||
"conditional",
|
||||
"divider",
|
||||
"section",
|
||||
"select",
|
||||
"weblink",
|
||||
]);
|
||||
const LAZY_LOAD_TYPES = {
|
||||
"climate-entity": () => import("../entity-rows/hui-climate-entity-row"),
|
||||
"cover-entity": () => import("../entity-rows/hui-cover-entity-row"),
|
||||
"group-entity": () => import("../entity-rows/hui-group-entity-row"),
|
||||
"input-datetime-entity": () =>
|
||||
import("../entity-rows/hui-input-datetime-entity-row"),
|
||||
"input-number-entity": () =>
|
||||
import("../entity-rows/hui-input-number-entity-row"),
|
||||
"input-select-entity": () =>
|
||||
import("../entity-rows/hui-input-select-entity-row"),
|
||||
"input-text-entity": () => import("../entity-rows/hui-input-text-entity-row"),
|
||||
"lock-entity": () => import("../entity-rows/hui-lock-entity-row"),
|
||||
"timer-entity": () => import("../entity-rows/hui-timer-entity-row"),
|
||||
conditional: () => import("../special-rows/hui-conditional-row"),
|
||||
divider: () => import("../special-rows/hui-divider-row"),
|
||||
section: () => import("../special-rows/hui-section-row"),
|
||||
weblink: () => import("../special-rows/hui-weblink-row"),
|
||||
cast: () => import("../special-rows/hui-cast-row"),
|
||||
};
|
||||
const DOMAIN_TO_ELEMENT_TYPE = {
|
||||
_domain_not_found: "text",
|
||||
alert: "toggle",
|
||||
@ -60,4 +65,11 @@ const DOMAIN_TO_ELEMENT_TYPE = {
|
||||
};
|
||||
|
||||
export const createRowElement = (config: EntityConfig) =>
|
||||
createLovelaceElement("row", config, SPECIAL_TYPES, DOMAIN_TO_ELEMENT_TYPE);
|
||||
createLovelaceElement(
|
||||
"row",
|
||||
config,
|
||||
ALWAYS_LOADED_TYPES,
|
||||
LAZY_LOAD_TYPES,
|
||||
DOMAIN_TO_ELEMENT_TYPE,
|
||||
undefined
|
||||
);
|
||||
|
5
src/panels/lovelace/custom-card-helpers.ts
Normal file
5
src/panels/lovelace/custom-card-helpers.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export { createRowElement } from "./create-element/create-row-element";
|
||||
export { createCardElement } from "./create-element/create-card-element";
|
||||
export { createBadgeElement } from "./create-element/create-badge-element";
|
||||
export { createHeaderFooterElement } from "./create-element/create-header-footer-element";
|
||||
export { createHuiElement } from "./create-element/create-hui-element";
|
@ -18,7 +18,7 @@ const cards: string[] = [
|
||||
"alarm-panel",
|
||||
"conditional",
|
||||
"entities",
|
||||
"entity-button",
|
||||
"button",
|
||||
"entity-filter",
|
||||
"gauge",
|
||||
"glance",
|
||||
|
@ -22,7 +22,7 @@ import { LovelaceCardEditor } from "../../types";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { configElementStyle } from "./config-elements-style";
|
||||
import { ActionConfig } from "../../../../data/lovelace";
|
||||
import { EntityButtonCardConfig } from "../../cards/types";
|
||||
import { ButtonCardConfig } from "../../cards/types";
|
||||
|
||||
const cardConfigStruct = struct({
|
||||
type: "string",
|
||||
@ -37,14 +37,14 @@ const cardConfigStruct = struct({
|
||||
theme: "string?",
|
||||
});
|
||||
|
||||
@customElement("hui-entity-button-card-editor")
|
||||
export class HuiEntityButtonCardEditor extends LitElement
|
||||
@customElement("hui-button-card-editor")
|
||||
export class HuiButtonCardEditor extends LitElement
|
||||
implements LovelaceCardEditor {
|
||||
@property() public hass?: HomeAssistant;
|
||||
|
||||
@property() private _config?: EntityButtonCardConfig;
|
||||
@property() private _config?: ButtonCardConfig;
|
||||
|
||||
public setConfig(config: EntityButtonCardConfig): void {
|
||||
public setConfig(config: ButtonCardConfig): void {
|
||||
config = cardConfigStruct(config);
|
||||
this._config = config;
|
||||
}
|
||||
@ -108,7 +108,7 @@ export class HuiEntityButtonCardEditor extends LitElement
|
||||
.label="${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.card.generic.entity"
|
||||
)} (${this.hass.localize(
|
||||
"ui.panel.lovelace.editor.card.config.required"
|
||||
"ui.panel.lovelace.editor.card.config.optional"
|
||||
)})"
|
||||
.hass="${this.hass}"
|
||||
.value="${this._entity}"
|
||||
@ -250,6 +250,6 @@ export class HuiEntityButtonCardEditor extends LitElement
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-entity-button-card-editor": HuiEntityButtonCardEditor;
|
||||
"hui-button-card-editor": HuiButtonCardEditor;
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
||||
throw Error("Invalid Configuration: 'entity' required");
|
||||
}
|
||||
|
||||
this._config = config;
|
||||
this._config = { state_color: true, ...config };
|
||||
}
|
||||
|
||||
protected shouldUpdate(changedProps: PropertyValues): boolean {
|
||||
@ -71,7 +71,7 @@ export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
||||
hasAction(this._config.tap_action) ? "0" : undefined
|
||||
)}
|
||||
.overrideIcon=${this._config.icon}
|
||||
stateColor
|
||||
.stateColor=${this._config.state_color}
|
||||
></state-badge>
|
||||
`;
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ export interface StateIconElementConfig extends LovelaceElementConfig {
|
||||
hold_action?: ActionConfig;
|
||||
double_tap_action?: ActionConfig;
|
||||
icon?: string;
|
||||
state_color?: boolean;
|
||||
}
|
||||
|
||||
export interface StateLabelElementConfig extends LovelaceElementConfig {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "@material/mwc-button";
|
||||
import * as deepFreeze from "deep-freeze";
|
||||
|
||||
import {
|
||||
fetchConfig,
|
||||
@ -24,6 +25,8 @@ import { showSaveDialog } from "./editor/show-save-config-dialog";
|
||||
import { generateLovelaceConfigFromHass } from "./common/generate-lovelace-config";
|
||||
import { showToast } from "../../util/toast";
|
||||
|
||||
(window as any).loadCardHelpers = () => import("./custom-card-helpers");
|
||||
|
||||
interface LovelacePanelConfig {
|
||||
mode: "yaml" | "storage";
|
||||
}
|
||||
@ -263,15 +266,22 @@ class LovelacePanel extends LitElement {
|
||||
|
||||
private _checkLovelaceConfig(config: LovelaceConfig) {
|
||||
// Somehow there can be badges with value null, we remove those
|
||||
config.views.forEach((view) => {
|
||||
if (view.badges) {
|
||||
view.badges = view.badges.filter(Boolean);
|
||||
let checkedConfig = !Object.isFrozen(config) ? config : undefined;
|
||||
config.views.forEach((view, index) => {
|
||||
if (view.badges && !view.badges.every(Boolean)) {
|
||||
checkedConfig = checkedConfig || {
|
||||
...config,
|
||||
views: [...config.views],
|
||||
};
|
||||
checkedConfig.views[index] = { ...view };
|
||||
checkedConfig.views[index].badges = view.badges.filter(Boolean);
|
||||
}
|
||||
});
|
||||
return checkedConfig ? deepFreeze(checkedConfig) : config;
|
||||
}
|
||||
|
||||
private _setLovelaceConfig(config: LovelaceConfig, mode: Lovelace["mode"]) {
|
||||
this._checkLovelaceConfig(config);
|
||||
config = this._checkLovelaceConfig(config);
|
||||
this.lovelace = {
|
||||
config,
|
||||
mode,
|
||||
@ -295,7 +305,7 @@ class LovelacePanel extends LitElement {
|
||||
},
|
||||
saveConfig: async (newConfig: LovelaceConfig): Promise<void> => {
|
||||
const { config: previousConfig, mode: previousMode } = this.lovelace!;
|
||||
this._checkLovelaceConfig(newConfig);
|
||||
newConfig = this._checkLovelaceConfig(newConfig);
|
||||
try {
|
||||
// Optimistic update
|
||||
this._updateLovelace({
|
||||
|
@ -94,6 +94,47 @@ export const haStyle = css`
|
||||
.card-actions .warning {
|
||||
--mdc-theme-primary: var(--google-red-500);
|
||||
}
|
||||
|
||||
.layout.horizontal,
|
||||
.layout.vertical {
|
||||
display: flex;
|
||||
}
|
||||
.layout.inline {
|
||||
display: inline-flex;
|
||||
}
|
||||
.layout.horizontal {
|
||||
flex-direction: row;
|
||||
}
|
||||
.layout.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
.layout.wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.layout.no-wrap {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.layout.center,
|
||||
.layout.center-center {
|
||||
align-items: center;
|
||||
}
|
||||
.layout.center-justified,
|
||||
.layout.center-center {
|
||||
justify-content: center;
|
||||
}
|
||||
.flex {
|
||||
flex: 1;
|
||||
flex-basis: 0.000000001px;
|
||||
}
|
||||
.flex-auto {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.flex-none {
|
||||
flex: none;
|
||||
}
|
||||
.layout.justified {
|
||||
justify-content: space-between;
|
||||
}
|
||||
`;
|
||||
|
||||
export const haStyleDialog = css`
|
||||
|
@ -572,6 +572,7 @@
|
||||
"service": "Service"
|
||||
},
|
||||
"related-items": {
|
||||
"no_related_found": "No related items found.",
|
||||
"integration": "Integration",
|
||||
"device": "Device",
|
||||
"area": "Area",
|
||||
@ -630,6 +631,9 @@
|
||||
"locate": "Locate",
|
||||
"return_home": "Return home",
|
||||
"start_pause": "Start/Pause"
|
||||
},
|
||||
"person": {
|
||||
"create_zone": "Create zone from current location"
|
||||
}
|
||||
},
|
||||
"entity_registry": {
|
||||
@ -637,6 +641,7 @@
|
||||
"control": "Control",
|
||||
"related": "Related",
|
||||
"dismiss": "Dismiss",
|
||||
"no_unique_id": "This entity does not have a unique ID, therefore it's settings can not be managed from the UI.",
|
||||
"editor": {
|
||||
"name": "Name Override",
|
||||
"entity_id": "Entity ID",
|
||||
@ -785,7 +790,7 @@
|
||||
"validation": {
|
||||
"heading": "Configuration validation",
|
||||
"introduction": "Validate your configuration if you recently made some changes to your configuration and want to make sure that it is all valid",
|
||||
"check_config": "Check config",
|
||||
"check_config": "Check configuration",
|
||||
"valid": "Configuration valid!",
|
||||
"invalid": "Configuration invalid"
|
||||
},
|
||||
@ -847,6 +852,7 @@
|
||||
"delete_confirm": "Are you sure you want to delete this automation?"
|
||||
},
|
||||
"editor": {
|
||||
"enable_disable": "Enable/Disable automation",
|
||||
"introduction": "Use automations to bring your home alive.",
|
||||
"default_name": "New Automation",
|
||||
"load_error_not_editable": "Only automations in automations.yaml are editable.",
|
||||
@ -1206,7 +1212,7 @@
|
||||
"title": "Alexa",
|
||||
"info": "With the Alexa integration for Home Assistant Cloud you'll be able to control all your Home Assistant devices via any Alexa-enabled device.",
|
||||
"enable_ha_skill": "Enable the Home Assistant skill for Alexa",
|
||||
"config_documentation": "Config documentation",
|
||||
"config_documentation": "Configuration documentation",
|
||||
"enable_state_reporting": "Enable State Reporting",
|
||||
"info_state_reporting": "If you enable state reporting, Home Assistant will send all state changes of exposed entities to Amazon. This allows you to always see the latest states in the Alexa app and use the state changes to create routines.",
|
||||
"sync_entities": "Sync Entities",
|
||||
@ -1220,7 +1226,7 @@
|
||||
"title": "Google Assistant",
|
||||
"info": "With the Google Assistant integration for Home Assistant Cloud you'll be able to control all your Home Assistant devices via any Google Assistant-enabled device.",
|
||||
"enable_ha_skill": "Activate the Home Assistant skill for Google Assistant",
|
||||
"config_documentation": "Config documentation",
|
||||
"config_documentation": "Configuration documentation",
|
||||
"enable_state_reporting": "Enable State Reporting",
|
||||
"info_state_reporting": "If you enable state reporting, Home Assistant will send all state changes of exposed entities to Google. This allows you to always see the latest states in the Google app.",
|
||||
"security_devices": "Security Devices",
|
||||
@ -1341,11 +1347,13 @@
|
||||
"filter": {
|
||||
"filter": "Filter",
|
||||
"show_disabled": "Show disabled entities",
|
||||
"show_unavailable": "Show unavailable entities"
|
||||
"show_unavailable": "Show unavailable entities",
|
||||
"show_readonly": "Show read-only entities"
|
||||
},
|
||||
"status": {
|
||||
"unavailable": "Unavailable",
|
||||
"disabled": "Disabled",
|
||||
"readonly": "Read-only",
|
||||
"ok": "Ok"
|
||||
},
|
||||
"headers": {
|
||||
@ -1407,7 +1415,10 @@
|
||||
"add_zone": "Add Zone",
|
||||
"confirm_delete": "Are you sure you want to delete this zone?",
|
||||
"configured_in_yaml": "Zones configured via configuration.yaml cannot be edited via the UI.",
|
||||
"edit_home_zone": "The location of your home can be changed in the general config.",
|
||||
"edit_home_zone": "The radius of the Home zone can't be edited from the frontend yet. Drag the marker on the map to move the home zone.",
|
||||
"edit_home_zone_narrow": "The radius of the Home zone can't be edited from the frontend yet. The location can be changed from the general configuration.",
|
||||
"go_to_core_config": "Go to general configuration?",
|
||||
"home_zone_core_config": "The location of your home zone is editable from the general configuration page. The radius of the Home zone can't be edited from the frontend yet. Do you want to go to the general configuration?",
|
||||
"detail": {
|
||||
"new_zone": "New Zone",
|
||||
"name": "Name",
|
||||
@ -1472,7 +1483,7 @@
|
||||
"submit": "Submit",
|
||||
"not_all_required_fields": "Not all required fields are filled in.",
|
||||
"error_saving_area": "Error saving area: {error}",
|
||||
"created_config": "Created config for {name}.",
|
||||
"created_config": "Created configuration for {name}.",
|
||||
"external_step": {
|
||||
"description": "This step requires you to visit an external website to be completed.",
|
||||
"open_site": "Open website"
|
||||
@ -1639,14 +1650,14 @@
|
||||
"network_started_note_all_queried": "All nodes have been queried."
|
||||
},
|
||||
"node_config": {
|
||||
"header": "Node Config Options",
|
||||
"header": "Node Configuration Options",
|
||||
"seconds": "seconds",
|
||||
"set_wakeup": "Set Wakeup Interval",
|
||||
"config_parameter": "Config Parameter",
|
||||
"config_value": "Config Value",
|
||||
"config_parameter": "Configuration Parameter",
|
||||
"config_value": "Configuration Value",
|
||||
"true": "True",
|
||||
"false": "False",
|
||||
"set_config_parameter": "Set Config Parameter"
|
||||
"set_config_parameter": "Set Configuration Parameter"
|
||||
},
|
||||
"values": {
|
||||
"header": "Node Values"
|
||||
@ -1657,7 +1668,7 @@
|
||||
"heal_network": "Heal Network",
|
||||
"test_network": "Test Network",
|
||||
"soft_reset": "Soft Reset",
|
||||
"save_config": "Save Config",
|
||||
"save_config": "Save Configuration",
|
||||
"add_node_secure": "Add Node Secure",
|
||||
"add_node": "Add Node",
|
||||
"remove_node": "Remove Node",
|
||||
@ -1712,7 +1723,7 @@
|
||||
"add_entities": {
|
||||
"yaml_unsupported": "You can not use this function when using Lovelace UI in YAML mode.",
|
||||
"generated_unsupported": "You can only use this function when you have taken control of the Lovelace UI.",
|
||||
"saving_failed": "Saving Lovelace UI config failed."
|
||||
"saving_failed": "Saving Lovelace UI configuration failed."
|
||||
},
|
||||
"views": {
|
||||
"confirm_delete": "Are you sure you want to delete this view?",
|
||||
@ -1729,21 +1740,21 @@
|
||||
"header": "Edit UI",
|
||||
"menu": {
|
||||
"open": "Open Lovelace UI menu",
|
||||
"raw_editor": "Raw config editor"
|
||||
"raw_editor": "Raw configuration editor"
|
||||
},
|
||||
"raw_editor": {
|
||||
"header": "Edit Config",
|
||||
"header": "Edit Configuration",
|
||||
"save": "Save",
|
||||
"unsaved_changes": "Unsaved changes",
|
||||
"saved": "Saved",
|
||||
"confirm_remove_config_title": "Are you sure you want to remove your Lovelace UI configuration? We will automatically generate your Lovelace UI views with your areas and devices.",
|
||||
"confirm_remove_config_text": "We will automatically generate your Lovelace UI views with your areas and devices if you remove your Lovelace UI configuration.",
|
||||
"confirm_unsaved_changes": "You have unsaved changes, are you sure you want to exit?",
|
||||
"confirm_unsaved_comments": "Your config contains comment(s), these will not be saved. Do you want to continue?",
|
||||
"confirm_unsaved_comments": "Your configuration contains comment(s), these will not be saved. Do you want to continue?",
|
||||
"error_parse_yaml": "Unable to parse YAML: {error}",
|
||||
"error_invalid_config": "Your config is not valid: {error}",
|
||||
"error_invalid_config": "Your configuration is not valid: {error}",
|
||||
"error_save_yaml": "Unable to save YAML: {error}",
|
||||
"error_remove": "Unable to remove config: {error}"
|
||||
"error_remove": "Unable to remove configuration: {error}"
|
||||
},
|
||||
"edit_lovelace": {
|
||||
"header": "Title of your Lovelace UI",
|
||||
@ -1787,8 +1798,8 @@
|
||||
"migrate": {
|
||||
"header": "Configuration Incompatible",
|
||||
"para_no_id": "This element doesn't have an ID. Please add an ID to this element in 'ui-lovelace.yaml'.",
|
||||
"para_migrate": "Home Assistant can add ID's to all your cards and views automatically for you by pressing the 'Migrate config' button.",
|
||||
"migrate": "Migrate config"
|
||||
"para_migrate": "Home Assistant can add ID's to all your cards and views automatically for you by pressing the 'Migrate configuration' button.",
|
||||
"migrate": "Migrate configuration"
|
||||
},
|
||||
"card": {
|
||||
"alarm-panel": {
|
||||
@ -1807,8 +1818,8 @@
|
||||
"show_header_toggle": "Show Header Toggle?",
|
||||
"toggle": "Toggle entities."
|
||||
},
|
||||
"entity-button": {
|
||||
"name": "Entity Button"
|
||||
"button": {
|
||||
"name": "Button"
|
||||
},
|
||||
"entity-filter": {
|
||||
"name": "Entity Filter"
|
||||
@ -2086,7 +2097,7 @@
|
||||
"data": {
|
||||
"password": "API Password"
|
||||
},
|
||||
"description": "Please input the API password in your http config:"
|
||||
"description": "Please input the API password in your HTTP configuration:"
|
||||
},
|
||||
"mfa": {
|
||||
"data": {
|
||||
|
@ -52,7 +52,7 @@
|
||||
"switch": "Interruptors",
|
||||
"system_health": "Estat del Sistema",
|
||||
"updater": "Actualitzador",
|
||||
"vacuum": "Aspiradora",
|
||||
"vacuum": "Aspirador",
|
||||
"weblink": "Enllaços web",
|
||||
"zha": "ZHA",
|
||||
"zwave": "Z-Wave"
|
||||
@ -354,12 +354,12 @@
|
||||
},
|
||||
"vacuum": {
|
||||
"cleaning": "Netejant",
|
||||
"docked": "Aparcada",
|
||||
"docked": "Aparcat",
|
||||
"error": "Error",
|
||||
"idle": "Inactiu",
|
||||
"off": "Apagada",
|
||||
"on": "Encesa",
|
||||
"paused": "Pausada",
|
||||
"off": "Apagat",
|
||||
"on": "Encès",
|
||||
"paused": "Pausat",
|
||||
"returning": "Retornant a la base"
|
||||
},
|
||||
"weather": {
|
||||
@ -492,10 +492,10 @@
|
||||
"vacuum": {
|
||||
"actions": {
|
||||
"resume_cleaning": "Reprendre neteja",
|
||||
"return_to_base": "Retornar a la base",
|
||||
"start_cleaning": "Començar neteja",
|
||||
"turn_off": "Apagar",
|
||||
"turn_on": "Encendre"
|
||||
"return_to_base": "Retorna a la base",
|
||||
"start_cleaning": "Comença neteja",
|
||||
"turn_off": "Apaga",
|
||||
"turn_on": "Encén"
|
||||
}
|
||||
},
|
||||
"water_heater": {
|
||||
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Si està desactivat, les entitats recentment descobertes per a {integration} no s’afegiran automàticament a Home Assistant.",
|
||||
"enable_new_entities_label": "Activa entitats afegides recentment.",
|
||||
"title": "Opcions del sistema per a {integration}"
|
||||
"title": "Opcions del sistema per a {integration}",
|
||||
"update": "Actualitza"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Cancel·la",
|
||||
@ -640,8 +641,13 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Desestimar el diàleg",
|
||||
"edit": "Edita entitat",
|
||||
"person": {
|
||||
"create_zone": "Crea una zona a partir de la ubicació actual"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Estàs segur que vols eliminar aquesta entitat?",
|
||||
"confirm_remove_title": "Eliminar l'entitat?",
|
||||
"not_provided": "Actualment aquesta entitat no està disponible, prové d'una integració o dispositiu eliminat, modificat o que no funciona.",
|
||||
"remove_action": "Elimina entitat",
|
||||
"remove_intro": "Si l'entitat ja no s'utilitza, pots borrar-la eliminant-la."
|
||||
},
|
||||
@ -657,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instruccions d'actualització"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Zona neta",
|
||||
"commands": "Comandes de l’aspirador:",
|
||||
"fan_speed": "Velocitat del ventilador",
|
||||
"locate": "Localitza",
|
||||
"pause": "Pausa",
|
||||
"return_home": "Torna a casa",
|
||||
"start": "Inici",
|
||||
"start_pause": "Inicia/Pausa",
|
||||
"status": "Estat",
|
||||
"stop": "Atura"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -877,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Edita a través d'interfície",
|
||||
"edit_yaml": "Edita com a YAML",
|
||||
"enable_disable": "Activa/desactiva automatització",
|
||||
"introduction": "Utilitza les automatitzacions per donar més vida a la teva casa",
|
||||
"load_error_not_editable": "Només es poden editar les automatitzacions de l'arxiu automations.yaml.",
|
||||
"load_error_unknown": "Error en carregar l’automatització ({err_no}).",
|
||||
@ -1020,6 +1039,7 @@
|
||||
"manage_entities": "Gestió d'entitats",
|
||||
"security_devices": "Dispositius de seguretat",
|
||||
"sync_entities": "Sincronitza les entitats amb Google",
|
||||
"sync_entities_404_message": "No s'han pogut sincronitzar les entitats amb Google, digues \"Hey Google, sincronitza els meus dispositius\" per sincronitzar-les.",
|
||||
"title": "Google Assistant"
|
||||
},
|
||||
"integrations": "Integracions",
|
||||
@ -1640,6 +1660,7 @@
|
||||
"zha_zigbee_groups": "Grups ZHA Zigbee"
|
||||
},
|
||||
"header": "Configuració domòtica Zigbee (ZHA)",
|
||||
"introduction": "Des d'aquí pots configurar el component ZHA. Encara no és possible configurar-ho tot des de la interfície d'usuari, però hi estem treballant.",
|
||||
"network_management": {
|
||||
"header": "Gestió de la xarxa",
|
||||
"introduction": "Comandes que afecten tota la xarxa"
|
||||
@ -1907,6 +1928,9 @@
|
||||
"available_states": "Estats disponibles",
|
||||
"name": "Panell d'alarma"
|
||||
},
|
||||
"button": {
|
||||
"name": "Botó"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Condicional"
|
||||
},
|
||||
@ -2062,6 +2086,8 @@
|
||||
"para_no_id": "Aquest element no té ID. Afegeix un ID per aquest element a 'ui-lovelace.yaml'."
|
||||
},
|
||||
"raw_editor": {
|
||||
"confirm_remove_config_text": "Si elimines la configuració de la interfície d'usuari Lovelace es generaran automàticament les visualitzacions de Lovelace amb les teves àrees i dispositius.",
|
||||
"confirm_remove_config_title": "Estàs segur que vols eliminar la configuració de la interfície d'usuari Lovelace? Es generaran automàticament les visualitzacions de Lovelace amb les teves àrees i dispositius.",
|
||||
"confirm_unsaved_changes": "Hi han canvis no desats. Segur que vols sortir?",
|
||||
"confirm_unsaved_comments": "La configuració conté comentaris que es descartaran. Vols continuar?",
|
||||
"error_invalid_config": "La configuració no és vàlida: {error}",
|
||||
@ -2082,7 +2108,8 @@
|
||||
},
|
||||
"suggest_card": {
|
||||
"add": "Afegeix a la UI Lovelace",
|
||||
"create_own": "Crea la teva"
|
||||
"create_own": "Crea la teva",
|
||||
"header": "T'hem creat un suggeriment"
|
||||
},
|
||||
"view": {
|
||||
"panel_mode": {
|
||||
|
@ -659,6 +659,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Pokyny pro aktualizaci"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Čisté místo",
|
||||
"commands": "Příkazy vysavače:",
|
||||
"fan_speed": "Rychlost ventilátoru",
|
||||
"locate": "Lokalizovat",
|
||||
"pause": "Pauza",
|
||||
"return_home": "Návrat domů",
|
||||
"start": "Start",
|
||||
"start_pause": "Start / Pauza",
|
||||
"status": "Stav",
|
||||
"stop": "Stop"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Hvis deaktiveret, tilføjes nyligt opdagede entiteter fra {integration} ikke automatisk til Home Assistant.",
|
||||
"enable_new_entities_label": "Aktivér nyligt tilføjede entiteter.",
|
||||
"title": "Systemindstillinger for {integration}"
|
||||
"title": "Systemindstillinger for {integration}",
|
||||
"update": "Opdater"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Annuller",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Afvis dialog",
|
||||
"edit": "Rediger entitet",
|
||||
"person": {
|
||||
"create_zone": "Opret zone fra den aktuelle lokalitet"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Er du sikker på, at du vil fjerne denne entitet?",
|
||||
"confirm_remove_title": "Fjern entitet?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Opdateringsvejledning"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Rengør sted",
|
||||
"commands": "Støvsuger kommandoer",
|
||||
"fan_speed": "Blæserhastighed",
|
||||
"locate": "Lokaliser",
|
||||
"pause": "Pause",
|
||||
"return_home": "Retur til ladestation",
|
||||
"start": "Start",
|
||||
"start_pause": "Start/Pause",
|
||||
"status": "Status",
|
||||
"stop": "Stop"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Rediger brugerflade",
|
||||
"edit_yaml": "Rediger med YAML",
|
||||
"enable_disable": "Aktiver/deaktiver automatisering",
|
||||
"introduction": "Brug automatiseringer til at vække dit hjem til live.",
|
||||
"load_error_not_editable": "Kun automatiseringer i 'automations.yaml' kan redigeres.",
|
||||
"load_error_unknown": "Fejl ved indlæsning af automatisering ({err_no}).",
|
||||
@ -1359,7 +1376,7 @@
|
||||
"add_area": "Tilføj område",
|
||||
"area_picker_label": "Område",
|
||||
"close": "Luk",
|
||||
"created_config": "Oprettede konfiguration til {name}.",
|
||||
"created_config": "Oprettede konfiguration for {name}.",
|
||||
"dismiss": "Afvis dialog",
|
||||
"error_saving_area": "Fejl ved lagring af område: {error}",
|
||||
"external_step": {
|
||||
@ -1496,8 +1513,8 @@
|
||||
"automation": "Genindlæs automatiseringer",
|
||||
"core": "Genindlæs lokalitet og tilpasninger",
|
||||
"group": "Genindlæs grupper",
|
||||
"heading": "Genindlæser konfiguration",
|
||||
"introduction": "Nogle dele af Home Assistant kan genindlæses uden en genstart. Tryk på genindlæs for at aflæse den nuværende konfiguration og indlæse den nye.",
|
||||
"heading": "YAML-konfiguration genindlæses",
|
||||
"introduction": "Nogle dele af Home Assistant kan genindlæses uden en genstart. Tryk på genindlæs for at aflæse den nuværende YAML-konfiguration og indlæse den nye.",
|
||||
"person": "Genindlæs personer",
|
||||
"scene": "Genindlæs scener",
|
||||
"script": "Genindlæs scripts",
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Tilgængelige tilstande",
|
||||
"name": "Alarmpanel"
|
||||
},
|
||||
"button": {
|
||||
"name": "Knap"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Betinget"
|
||||
},
|
||||
@ -2062,7 +2082,7 @@
|
||||
"migrate": {
|
||||
"header": "Konfigurationen er ikke kompatibel",
|
||||
"migrate": "Migrer opsætning",
|
||||
"para_migrate": "Home Assistant kan tilføje id'er til alle dine kort og oversigter automatisk for dig ved at trykke på knappen 'Migrer opsætning'.",
|
||||
"para_migrate": "Home Assistant kan tilføje id'er til alle dine kort og visninger automatisk for dig ved at trykke på knappen 'Migrer opsætning'.",
|
||||
"para_no_id": "Dette element har ikke et id. Tilføj venligst et id til dette element i 'ui-lovelace.yaml'."
|
||||
},
|
||||
"raw_editor": {
|
||||
|
@ -604,12 +604,13 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Wenn deaktiviert werden neu erkannte Entitäten für {integration} nicht automatisch zu Home Assistant hinzugefügt.",
|
||||
"enable_new_entities_label": "Neu hinzugefügte Entitäten aktivieren.",
|
||||
"title": "Einstellungen für {integration}"
|
||||
"title": "Einstellungen für {integration}",
|
||||
"update": "Aktualisieren"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Abbrechen",
|
||||
"ok": "OK",
|
||||
"title": "Bist Sie sicher?"
|
||||
"title": "Sind Sie sicher?"
|
||||
},
|
||||
"domain_toggler": {
|
||||
"title": "Domänen umschalten"
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Dialog ausblenden",
|
||||
"edit": "Entität bearbeiten",
|
||||
"person": {
|
||||
"create_zone": "Zone vom aktuellen Standort erstellen"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Sind Sie sicher, dass Sie diese Entität löschen möchten?",
|
||||
"confirm_remove_title": "Entität entfernen?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Update-Anweisungen"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Stelle säubern",
|
||||
"commands": "Staubsaugerbefehle:",
|
||||
"fan_speed": "Lüftergeschwindigkeit",
|
||||
"locate": "Lokalisieren",
|
||||
"pause": "Pause",
|
||||
"return_home": "Zum Hub zurückkehren",
|
||||
"start": "Start",
|
||||
"start_pause": "Start/Pause",
|
||||
"status": "Status",
|
||||
"stop": "Stoppen"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Bearbeiten Sie mit der Benutzeroberfläche",
|
||||
"edit_yaml": "Als YAML bearbeiten",
|
||||
"enable_disable": "Automatisierung aktivieren / deaktivieren",
|
||||
"introduction": "Benutze Automatisierungen, um deinem Zuhause Leben einzuhauchen",
|
||||
"load_error_not_editable": "Nur Automatisierungen in automations.yaml sind editierbar.",
|
||||
"load_error_unknown": "Fehler beim Laden der Automatisierung ({err_no}).",
|
||||
@ -1079,7 +1096,7 @@
|
||||
"close": "Schließen",
|
||||
"confirm_disable": "Möchten Sie diesen Webhook wirklich deaktivieren?",
|
||||
"copied_to_clipboard": "In die Zwischenablage kopiert",
|
||||
"info_disable_webhook": "Wenn Sie diesen Webhook nicht mehr nutzen wollen, können Sie ",
|
||||
"info_disable_webhook": "Wenn Sie diesen Webhook nicht mehr nutzen wollen, können Sie",
|
||||
"link_disable_webhook": "deaktiviere es",
|
||||
"managed_by_integration": "Dieser Webhook wird von einer Integration verwaltet und kann nicht deaktiviert werden.",
|
||||
"view_documentation": "Dokumentation anzeigen",
|
||||
@ -1193,7 +1210,7 @@
|
||||
"validation": {
|
||||
"check_config": "Konfiguration prüfen",
|
||||
"heading": "Konfiguration überprüfen",
|
||||
"introduction": "Überprüfen der Konfiguration, wenn Sie kürzlich Änderungen vorgenommen haben und sicherstellen möchten, dass alles ordnungsgemäß ist",
|
||||
"introduction": "Überprüfen der Konfiguration, wenn Sie kürzlich Änderungen vorgenommen haben und sicherstellen möchten, dass alles ordnungsgemäß ist",
|
||||
"invalid": "Konfiguration fehlerhaft",
|
||||
"valid": "Konfiguration in Ordnung"
|
||||
}
|
||||
@ -1415,7 +1432,7 @@
|
||||
"name": "Name",
|
||||
"name_error_msg": "Name erforderlich",
|
||||
"new_person": "Neue Person",
|
||||
"no_device_tracker_available_intro": "Wenn Sie Geräte haben, die die Anwesenheit einer Person anzeigen, können Sie diese hier einer Person zuordnen. Sie können Ihr erstes Gerät hinzufügen, indem Sie eine Integration zur Anwesenheitserkennung auf der Integrationsseite hinzufügen.",
|
||||
"no_device_tracker_available_intro": "Wenn Sie Geräte haben, die die Anwesenheit einer Person anzeigen, können Sie diese hier einer Person zuordnen. Sie können Ihr erstes Gerät hinzufügen, indem Sie eine Integration zur Anwesenheitserkennung auf der Integrationsseite hinzufügen.",
|
||||
"update": "Aktualisieren"
|
||||
},
|
||||
"introduction": "Hier können Sie jede Person von Interesse in Home Assistant definieren.",
|
||||
@ -1656,7 +1673,7 @@
|
||||
"introduction": "ZHA-Befehle ausführen, die sich auf ein einzelnes Gerät auswirken. Wählen Sie ein Gerät aus, um eine Liste der verfügbaren Befehle anzuzeigen."
|
||||
},
|
||||
"services": {
|
||||
"reconfigure": "Rekonfigurieren des ZHA-Geräts (Gerät heilen). Benutzen Sie dies, wenn Sie Probleme mit dem Gerät haben. Wenn es sich bei dem betroffenden Gerät um ein batteriebetriebenes Gerät handelt, stellen Sie sicher, dass es wach ist und Kommandos akzeptiert, wenn Sie diesen Dienst benutzen.",
|
||||
"reconfigure": "Rekonfigurieren des ZHA-Geräts (Gerät heilen). Benutzen Sie dies, wenn Sie Probleme mit dem Gerät haben. Wenn es sich bei dem betroffenden Gerät um ein batteriebetriebenes Gerät handelt, stellen Sie sicher, dass es wach ist und Kommandos akzeptiert, wenn Sie diesen Dienst benutzen.",
|
||||
"remove": "Entferne ein Gerät aus dem Zigbee-Netzwerk.",
|
||||
"updateDeviceName": "Lege einen benutzerdefinierten Namen für dieses Gerät in der Geräteregistrierung fest."
|
||||
},
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Verfügbare Zustände",
|
||||
"name": "Alarmpanel"
|
||||
},
|
||||
"button": {
|
||||
"name": "Schaltfläche"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Bedingte Elemente"
|
||||
},
|
||||
@ -2067,7 +2087,7 @@
|
||||
},
|
||||
"raw_editor": {
|
||||
"confirm_remove_config_text": "Wir generieren automatisch deine Lovelace-Ansichten mit deinen Bereichen und Geräten, wenn Sie Ihre Lovelace-Konfiguration entfernen.",
|
||||
"confirm_remove_config_title": "Bist Ssie sicher, dass Sie Ihre deine Lovelace-Konfiguration entfernen ollen? Wir generieren automatisch Ihre Lovelace-Ansichten mit Ihren Bereichen und Geräten.",
|
||||
"confirm_remove_config_title": "Sind Sie sicher, dass Sie Ihre Lovelace-Konfiguration entfernen wollen? Wir generieren automatisch Ihre Lovelace-Ansichten mit Ihren Bereichen und Geräten.",
|
||||
"confirm_unsaved_changes": "Sie haben ungespeicherte Änderungen, sind Sie sicher, dass Sie beenden willen?",
|
||||
"confirm_unsaved_comments": "Ihre Konfiguration enthält einen oder mehrere Kommentare, diese werden nicht gespeichert. Möchten Sie fortfahren?",
|
||||
"error_invalid_config": "Deine Konfiguration ist ungültig: {error}",
|
||||
@ -2325,7 +2345,7 @@
|
||||
"language": {
|
||||
"dropdown_label": "Sprache",
|
||||
"header": "Sprache",
|
||||
"link_promo": "Hilf beim Übersetzen"
|
||||
"link_promo": "Hilfe beim Übersetzen"
|
||||
},
|
||||
"logout": "Abmelden",
|
||||
"logout_text": "Möchten Sie sich wirklich abmelden?",
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "If disabled, newly discovered entities for {integration} will not be automatically added to Home Assistant.",
|
||||
"enable_new_entities_label": "Enable newly added entities.",
|
||||
"title": "System Options for {integration}"
|
||||
"title": "System Options for {integration}",
|
||||
"update": "Update"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Cancel",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Dismiss dialog",
|
||||
"edit": "Edit entity",
|
||||
"person": {
|
||||
"create_zone": "Create zone from current location"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Are you sure you want to remove this entity?",
|
||||
"confirm_remove_title": "Remove entity?",
|
||||
@ -891,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Edit with UI",
|
||||
"edit_yaml": "Edit as YAML",
|
||||
"enable_disable": "Enable/Disable automation",
|
||||
"introduction": "Use automations to bring your home alive.",
|
||||
"load_error_not_editable": "Only automations in automations.yaml are editable.",
|
||||
"load_error_unknown": "Error loading automation ({err_no}).",
|
||||
@ -1005,7 +1010,7 @@
|
||||
"cloud": {
|
||||
"account": {
|
||||
"alexa": {
|
||||
"config_documentation": "Config documentation",
|
||||
"config_documentation": "Configuration documentation",
|
||||
"disable": "disable",
|
||||
"enable": "enable",
|
||||
"enable_ha_skill": "Enable the Home Assistant skill for Alexa",
|
||||
@ -1022,7 +1027,7 @@
|
||||
"connection_status": "Cloud connection status",
|
||||
"fetching_subscription": "Fetching subscription…",
|
||||
"google": {
|
||||
"config_documentation": "Config documentation",
|
||||
"config_documentation": "Configuration documentation",
|
||||
"devices_pin": "Security Devices Pin",
|
||||
"enable_ha_skill": "Activate the Home Assistant skill for Google Assistant",
|
||||
"enable_state_reporting": "Enable State Reporting",
|
||||
@ -1371,7 +1376,7 @@
|
||||
"add_area": "Add Area",
|
||||
"area_picker_label": "Area",
|
||||
"close": "Close",
|
||||
"created_config": "Created config for {name}.",
|
||||
"created_config": "Created configuration for {name}.",
|
||||
"dismiss": "Dismiss dialog",
|
||||
"error_saving_area": "Error saving area: {error}",
|
||||
"external_step": {
|
||||
@ -1524,7 +1529,7 @@
|
||||
"stop": "Stop"
|
||||
},
|
||||
"validation": {
|
||||
"check_config": "Check config",
|
||||
"check_config": "Check configuration",
|
||||
"heading": "Configuration validation",
|
||||
"introduction": "Validate your configuration if you recently made some changes to your configuration and want to make sure that it is all valid",
|
||||
"invalid": "Configuration invalid",
|
||||
@ -1696,7 +1701,7 @@
|
||||
"required_error_msg": "This field is required",
|
||||
"update": "Update"
|
||||
},
|
||||
"edit_home_zone": "The location of your home can be changed in the general config.",
|
||||
"edit_home_zone": "The location of your home can be changed in the general configuration.",
|
||||
"introduction": "Zones allow you to specify certain regions on earth. When a person is within a zone, the state will take the name from the zone. Zones can also be used as a trigger or condition inside automation setups.",
|
||||
"no_zones_created_yet": "Looks like you have not created any zones yet."
|
||||
},
|
||||
@ -1724,12 +1729,12 @@
|
||||
"network_stopped": "Z-Wave Network Stopped"
|
||||
},
|
||||
"node_config": {
|
||||
"config_parameter": "Config Parameter",
|
||||
"config_value": "Config Value",
|
||||
"config_parameter": "Configuration Parameter",
|
||||
"config_value": "Configuration Value",
|
||||
"false": "False",
|
||||
"header": "Node Config Options",
|
||||
"header": "Node Configuration Options",
|
||||
"seconds": "seconds",
|
||||
"set_config_parameter": "Set Config Parameter",
|
||||
"set_config_parameter": "Set Configuration Parameter",
|
||||
"set_wakeup": "Set Wakeup Interval",
|
||||
"true": "True"
|
||||
},
|
||||
@ -1743,7 +1748,7 @@
|
||||
"cancel_command": "Cancel Command",
|
||||
"heal_network": "Heal Network",
|
||||
"remove_node": "Remove Node",
|
||||
"save_config": "Save Config",
|
||||
"save_config": "Save Configuration",
|
||||
"soft_reset": "Soft Reset",
|
||||
"start_network": "Start Network",
|
||||
"stop_network": "Stop Network",
|
||||
@ -1882,7 +1887,7 @@
|
||||
"lovelace": {
|
||||
"add_entities": {
|
||||
"generated_unsupported": "You can only use this function when you have taken control of the Lovelace UI.",
|
||||
"saving_failed": "Saving Lovelace UI config failed.",
|
||||
"saving_failed": "Saving Lovelace UI configuration failed.",
|
||||
"yaml_unsupported": "You can not use this function when using Lovelace UI in YAML mode."
|
||||
},
|
||||
"cards": {
|
||||
@ -1923,6 +1928,9 @@
|
||||
"available_states": "Available States",
|
||||
"name": "Alarm Panel"
|
||||
},
|
||||
"button": {
|
||||
"name": "Button"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Conditional"
|
||||
},
|
||||
@ -2069,24 +2077,24 @@
|
||||
"header": "Edit UI",
|
||||
"menu": {
|
||||
"open": "Open Lovelace UI menu",
|
||||
"raw_editor": "Raw config editor"
|
||||
"raw_editor": "Raw configuration editor"
|
||||
},
|
||||
"migrate": {
|
||||
"header": "Configuration Incompatible",
|
||||
"migrate": "Migrate config",
|
||||
"para_migrate": "Home Assistant can add ID's to all your cards and views automatically for you by pressing the 'Migrate config' button.",
|
||||
"migrate": "Migrate configuration",
|
||||
"para_migrate": "Home Assistant can add ID's to all your cards and views automatically for you by pressing the 'Migrate configuration' button.",
|
||||
"para_no_id": "This element doesn't have an ID. Please add an ID to this element in 'ui-lovelace.yaml'."
|
||||
},
|
||||
"raw_editor": {
|
||||
"confirm_remove_config_text": "We will automatically generate your Lovelace UI views with your areas and devices if you remove your Lovelace UI configuration.",
|
||||
"confirm_remove_config_title": "Are you sure you want to remove your Lovelace UI configuration? We will automatically generate your Lovelace UI views with your areas and devices.",
|
||||
"confirm_unsaved_changes": "You have unsaved changes, are you sure you want to exit?",
|
||||
"confirm_unsaved_comments": "Your config contains comment(s), these will not be saved. Do you want to continue?",
|
||||
"error_invalid_config": "Your config is not valid: {error}",
|
||||
"confirm_unsaved_comments": "Your configuration contains comment(s), these will not be saved. Do you want to continue?",
|
||||
"error_invalid_config": "Your configuration is not valid: {error}",
|
||||
"error_parse_yaml": "Unable to parse YAML: {error}",
|
||||
"error_remove": "Unable to remove config: {error}",
|
||||
"error_remove": "Unable to remove configuration: {error}",
|
||||
"error_save_yaml": "Unable to save YAML: {error}",
|
||||
"header": "Edit Config",
|
||||
"header": "Edit Configuration",
|
||||
"save": "Save",
|
||||
"saved": "Saved",
|
||||
"unsaved_changes": "Unsaved changes"
|
||||
@ -2208,7 +2216,7 @@
|
||||
"data": {
|
||||
"password": "API Password"
|
||||
},
|
||||
"description": "Please input the API password in your http config:"
|
||||
"description": "Please input the API password in your HTTP configuration:"
|
||||
},
|
||||
"mfa": {
|
||||
"data": {
|
||||
|
@ -431,7 +431,9 @@
|
||||
"preset_mode": "Preestablecido",
|
||||
"swing_mode": "Modo de oscilación",
|
||||
"target_humidity": "Humedad deseada",
|
||||
"target_temperature": "Temperatura deseada"
|
||||
"target_temperature": "Temperatura deseada",
|
||||
"target_temperature_entity": "{name} temperatura objetivo",
|
||||
"target_temperature_mode": "{name} temperatura objetivo {mode}"
|
||||
},
|
||||
"counter": {
|
||||
"actions": {
|
||||
@ -657,6 +659,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instrucciones de actualización"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Lugar limpio",
|
||||
"commands": "Comandos de la aspiradora:",
|
||||
"fan_speed": "Velocidad del ventilador",
|
||||
"locate": "Localizar",
|
||||
"pause": "Pausar",
|
||||
"return_home": "Volver al inicio",
|
||||
"start": "Iniciar",
|
||||
"start_pause": "Iniciar/Pausar",
|
||||
"status": "Estado",
|
||||
"stop": "Detener"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -694,7 +708,9 @@
|
||||
"manuf": "por {manufacturer}",
|
||||
"no_area": "Sin área",
|
||||
"power_source": "Fuente de alimentación",
|
||||
"quirk": "Quirk",
|
||||
"services": {
|
||||
"reconfigure": "Reconfigure el dispositivo ZHA (dispositivo de curación). Use esto si tiene problemas con el dispositivo. Si el dispositivo en cuestión es un dispositivo alimentado por batería, asegúrese de que esté activado y acepte los comandos cuando utilice este servicio.",
|
||||
"remove": "Eliminar un dispositivo de la red ZigBee.",
|
||||
"updateDeviceName": "Establecer un nombre personalizado para este dispositivo en el registro de dispositivos."
|
||||
},
|
||||
@ -1204,6 +1220,7 @@
|
||||
"attributes_set": "Los siguientes atributos de la entidad se establecen mediante programación.",
|
||||
"caption": "Personalización",
|
||||
"description": "Personaliza tus entidades",
|
||||
"different_include": "Posiblemente a través de un dominio, un globo o una inclusión diferente.",
|
||||
"pick_attribute": "Elija un atributo para sobrescribir",
|
||||
"picker": {
|
||||
"header": "Personalización",
|
||||
@ -1211,12 +1228,16 @@
|
||||
},
|
||||
"warning": {
|
||||
"include_link": "incluir customize.yaml",
|
||||
"include_sentence": "Parece que tu configuration.yaml no funciona correctamente"
|
||||
"include_sentence": "Parece que tu configuration.yaml no funciona correctamente",
|
||||
"not_applied": "Los cambios realizados aquí están escritos, pero no se aplicarán después de una recarga de configuración a menos que la inclusión esté en su lugar."
|
||||
}
|
||||
},
|
||||
"devices": {
|
||||
"area_picker_label": "Área",
|
||||
"automation": {
|
||||
"actions": {
|
||||
"caption": "Cuando algo se desencadena..."
|
||||
},
|
||||
"automations": "Automatizaciones",
|
||||
"conditions": {
|
||||
"caption": "Sólo hacer algo si..."
|
||||
@ -1583,6 +1604,7 @@
|
||||
"add_devices": "Agregar dispositivos",
|
||||
"clusters": "Clústeres",
|
||||
"devices": "Dispositivos",
|
||||
"manufacturer_code_override": "Sobrescritura del código del fabricante",
|
||||
"value": "Valor"
|
||||
},
|
||||
"description": "Gestión de red de Zigbee Home Automation",
|
||||
@ -1594,6 +1616,17 @@
|
||||
"devices": {
|
||||
"header": "Zigbee Home Automation - Dispositivo"
|
||||
},
|
||||
"group_binding": {
|
||||
"bind_button_help": "Vincular el grupo seleccionado a los grupos de dispositivos seleccionados.",
|
||||
"bind_button_label": "Vincular grupo",
|
||||
"cluster_selection_help": "Seleccione los clústeres que desea enlazar al grupo seleccionado.",
|
||||
"group_picker_help": "Seleccione un grupo para emitir un comando de enlace.",
|
||||
"group_picker_label": "Grupos vinculables",
|
||||
"header": "Vinculación de grupo",
|
||||
"introduction": "Vincular y desvincular grupos.",
|
||||
"unbind_button_help": "Desvincular el grupo seleccionado de los grupos de dispositivos seleccionados.",
|
||||
"unbind_button_label": "Desvincular grupo"
|
||||
},
|
||||
"groups": {
|
||||
"add_members": "Agregar miembros",
|
||||
"adding_members": "Agregando miembros",
|
||||
@ -1630,6 +1663,7 @@
|
||||
"node_management": {
|
||||
"header": "Administración de dispositivos",
|
||||
"help_node_dropdown": "Seleccione un dispositivo para ver las opciones por dispositivo.",
|
||||
"hint_battery_devices": "Nota: Los dispositivos en reposo (alimentados por batería) deben estar despiertos al ejecutar comandos contra ellos. En general, puede activar un dispositivo en reposo activándolo.",
|
||||
"hint_wakeup": "Algunos dispositivos, como los sensores Xiaomi, tienen un botón de activación que puede presionar a intervalos de ~5 segundos para mantener los dispositivos activos mientras interactúa con ellos.",
|
||||
"introduction": "Ejecute comandos ZHA que afectan a un solo dispositivo. Elija un dispositivo para ver una lista de comandos disponibles."
|
||||
},
|
||||
@ -1643,6 +1677,7 @@
|
||||
"zone": {
|
||||
"add_zone": "Agregar zona",
|
||||
"caption": "Zonas",
|
||||
"configured_in_yaml": "Las zonas configuradas a través de configuration.yaml no se pueden editar a través de la interfaz de usuario.",
|
||||
"confirm_delete": "¿Está seguro de que desea eliminar esta zona?",
|
||||
"create_zone": "Crear zona",
|
||||
"description": "Administre las zonas en las que desea rastrear personas.",
|
||||
@ -1706,6 +1741,7 @@
|
||||
"add_node": "Agregar nodo",
|
||||
"add_node_secure": "Agregar nodo seguro",
|
||||
"cancel_command": "Cancelar comando",
|
||||
"heal_network": "Red de sanación",
|
||||
"remove_node": "Eliminar nodo",
|
||||
"save_config": "Guardar configuración",
|
||||
"soft_reset": "Reinicio suave",
|
||||
@ -1732,6 +1768,7 @@
|
||||
"available_events": "Eventos disponibles",
|
||||
"count_listeners": "({count} oyentes)",
|
||||
"data": "Datos del evento (YAML, opcional)",
|
||||
"description": "Desencadenar un evento en el bus de eventos.",
|
||||
"documentation": "Documentación de eventos.",
|
||||
"event_fired": "Evento {name} desencadenado",
|
||||
"fire_event": "Desencadenar evento",
|
||||
@ -1776,9 +1813,11 @@
|
||||
"title": "Registros"
|
||||
},
|
||||
"mqtt": {
|
||||
"description_listen": "Escuchar un tema",
|
||||
"description_publish": "Publicar un paquete",
|
||||
"listening_to": "Escuchando a",
|
||||
"message_received": "Mensaje {id} recibido el {topic} a las {time} :",
|
||||
"payload": "Carga útil (plantilla permitida)",
|
||||
"publish": "Publicar",
|
||||
"start_listening": "Comenzar a escuchar",
|
||||
"stop_listening": "Deja de escuchar",
|
||||
@ -1893,6 +1932,7 @@
|
||||
},
|
||||
"entities": {
|
||||
"name": "Entidades",
|
||||
"show_header_toggle": "¿Mostrar alternancia de encabezado?",
|
||||
"toggle": "Alternar entidades."
|
||||
},
|
||||
"entity-button": {
|
||||
@ -1902,6 +1942,7 @@
|
||||
"name": "Filtro de entidad"
|
||||
},
|
||||
"gauge": {
|
||||
"name": "Gauge",
|
||||
"severity": {
|
||||
"define": "¿Definir gravedad?",
|
||||
"green": "Verde",
|
||||
@ -1915,6 +1956,8 @@
|
||||
"camera_view": "Vista de la cámara",
|
||||
"entities": "Entidades",
|
||||
"entity": "Entidad",
|
||||
"hold_action": "Mantener la acción",
|
||||
"hours_to_show": "Horas para mostrar",
|
||||
"icon": "Icono",
|
||||
"icon_height": "Altura del icono",
|
||||
"image": "Ruta de la imagen",
|
||||
@ -1925,13 +1968,15 @@
|
||||
"show_icon": "¿Mostrar icono?",
|
||||
"show_name": "¿Mostrar nombre?",
|
||||
"show_state": "¿Mostrar estado?",
|
||||
"tap_action": "Acción de toque",
|
||||
"theme": "Tema",
|
||||
"title": "Título",
|
||||
"unit": "Unidad",
|
||||
"url": "Url"
|
||||
},
|
||||
"glance": {
|
||||
"columns": "Columnas"
|
||||
"columns": "Columnas",
|
||||
"name": "Glance"
|
||||
},
|
||||
"history-graph": {
|
||||
"name": "Gráfico histórico"
|
||||
@ -1953,7 +1998,8 @@
|
||||
"source": "Fuente"
|
||||
},
|
||||
"markdown": {
|
||||
"content": "Contenido"
|
||||
"content": "Contenido",
|
||||
"name": "Markdown"
|
||||
},
|
||||
"media-control": {
|
||||
"name": "Control multimedia"
|
||||
@ -1964,6 +2010,9 @@
|
||||
"picture-entity": {
|
||||
"name": "Entidad de imagen"
|
||||
},
|
||||
"picture-glance": {
|
||||
"name": "Picture Glance"
|
||||
},
|
||||
"picture": {
|
||||
"name": "Imagen"
|
||||
},
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Si está deshabilitada, las nuevas entidades que se descubran para {integration} no se añadirán automáticamente a Home Assistant.",
|
||||
"enable_new_entities_label": "Activar entidades recién añadidas.",
|
||||
"title": "Opciones del sistema para {integration}"
|
||||
"title": "Opciones del sistema para {integration}",
|
||||
"update": "Actualizar"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Cancelar",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Descartar diálogo",
|
||||
"edit": "Editar entidad",
|
||||
"person": {
|
||||
"create_zone": "Crear zona a partir de la ubicación actual"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "¿Estás seguro de que deseas eliminar esta entidad?",
|
||||
"confirm_remove_title": "¿Eliminar entidad?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instrucciones de actualización"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Limpiar punto",
|
||||
"commands": "Comandos de aspiradora:",
|
||||
"fan_speed": "Velocidad del ventilador",
|
||||
"locate": "Localizar",
|
||||
"pause": "Pausa",
|
||||
"return_home": "Volver a casa",
|
||||
"start": "Inicio",
|
||||
"start_pause": "Inicio/Pausa",
|
||||
"status": "Estado",
|
||||
"stop": "Detener"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Editar con la interfaz de usuario",
|
||||
"edit_yaml": "Editar como YAML",
|
||||
"enable_disable": "Activar/Desactivar automatización",
|
||||
"introduction": "Utiliza automatizaciones para darle vida a tu hogar.",
|
||||
"load_error_not_editable": "Solo las automatizaciones en automations.yaml son editables.",
|
||||
"load_error_unknown": "Error al cargar la automatización ({err_no}).",
|
||||
@ -1496,8 +1513,8 @@
|
||||
"automation": "Recargar automatizaciones",
|
||||
"core": "Recargar ubicación y personalizaciones",
|
||||
"group": "Recargar grupos",
|
||||
"heading": "Recargando la configuración",
|
||||
"introduction": "Algunas partes de Home Assistant pueden recargarse sin necesidad de reiniciar. Al pulsar en recargar se descartará la configuración actual y se cargará la nueva.",
|
||||
"heading": "Recargando la configuración YAML",
|
||||
"introduction": "Algunas partes de Home Assistant pueden recargarse sin necesidad de reiniciar. Al pulsar en recargar se descartará la configuración YAML actual y se cargará la nueva.",
|
||||
"person": "Recargar personas",
|
||||
"scene": "Recargar escenas",
|
||||
"script": "Recargar scripts",
|
||||
@ -1512,7 +1529,7 @@
|
||||
"stop": "Detener"
|
||||
},
|
||||
"validation": {
|
||||
"check_config": "Verificar la configuración",
|
||||
"check_config": "Verificar configuración",
|
||||
"heading": "Validación de la configuración",
|
||||
"introduction": "Valida tu configuración si has realizado cambios recientemente y quieres asegurarte de que son correctos",
|
||||
"invalid": "Configuración no válida",
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Estados disponibles",
|
||||
"name": "Panel de alarma"
|
||||
},
|
||||
"button": {
|
||||
"name": "Botón"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Condicional"
|
||||
},
|
||||
@ -2062,7 +2082,7 @@
|
||||
"migrate": {
|
||||
"header": "Configuración incompatible",
|
||||
"migrate": "Migrar configuración",
|
||||
"para_migrate": "Home Assistant puede añadir ID's a todas tus tarjetas y vistas automáticamente pulsando el botón 'Migrar configuración'.",
|
||||
"para_migrate": "Home Assistant puede añadir IDs a todas tus tarjetas y vistas automáticamente pulsando el botón 'Migrar configuración'.",
|
||||
"para_no_id": "Este elemento no tiene un ID. Por favor añade uno a este elemento en 'ui-lovelace.yaml'."
|
||||
},
|
||||
"raw_editor": {
|
||||
@ -2196,7 +2216,7 @@
|
||||
"data": {
|
||||
"password": "Contraseña de API"
|
||||
},
|
||||
"description": "Introduce la contraseña de la API en tu configuración http:"
|
||||
"description": "Introduce la contraseña de la API en tu configuración HTTP:"
|
||||
},
|
||||
"mfa": {
|
||||
"data": {
|
||||
|
@ -873,6 +873,7 @@
|
||||
"cloud": {
|
||||
"account": {
|
||||
"alexa": {
|
||||
"config_documentation": "Asetusten dokumentaatio.",
|
||||
"disable": "Poista käytöstä",
|
||||
"enable": "Ota käyttöön",
|
||||
"info": "Alexa Integraatio Home Assistant Cloudille mahdollistaa Home Assistant laitteiden ohjaamisen miltä tahansa Alexa laitteelta.",
|
||||
@ -883,6 +884,7 @@
|
||||
},
|
||||
"connected": "Yhdistetty",
|
||||
"google": {
|
||||
"config_documentation": "Asetusten dokumentaatio.",
|
||||
"enter_pin_error": "PIN-koodin tallentaminen ei onnistu:",
|
||||
"enter_pin_hint": "Anna PIN-koodi turvalaitteiden käyttämistä varten",
|
||||
"info": "Google Assistant Integraatio Home Assistant Cloudille mahdollistaa Home Assistant laitteiden ohjaamisen miltä tahansa Google Assistant laitteelta.",
|
||||
@ -1125,6 +1127,7 @@
|
||||
"add_area": "Lisää alue",
|
||||
"area_picker_label": "Alue",
|
||||
"close": "Sulje",
|
||||
"created_config": "Asetus luotu {name}",
|
||||
"external_step": {
|
||||
"description": "Tämä vaihe edellyttää, että vierailet ulkopuolisella verkkosivustolla.",
|
||||
"open_site": "Avaa verkkosivusto"
|
||||
@ -1224,6 +1227,7 @@
|
||||
"core": "Lataa ydin uudelleen",
|
||||
"group": "Lataa ryhmät uudelleen",
|
||||
"heading": "Asetusten uudelleenlataus",
|
||||
"introduction": "Jotkut kotiassistentin osat voidaan ladata uudelleen ilman, että tarvitaan uudelleenkäynnistystä. Painamalla uudelleenlatausta uudet asetukset luetaan yaml tiedostosta.",
|
||||
"scene": "Lataa tilanteet uudelleen",
|
||||
"script": "Lataa skriptit uudelleen"
|
||||
},
|
||||
@ -1330,6 +1334,12 @@
|
||||
"updateDeviceName": "Määritä laitteelle mukautettu nimeä laiterekisteriin."
|
||||
}
|
||||
},
|
||||
"zone": {
|
||||
"detail": {
|
||||
"passive_note": "Passiiviset vyöhykkeet on piilotetaan käyttöliittymässä, eikä niitä käytetä laitteiden paikannuksen sijaintina. Tämä on hyödyllistä, jos haluat käyttää vain automaatioihin."
|
||||
},
|
||||
"edit_home_zone": "Voit asettaa kotisi sijainnin kohdasta Asetukset>Yleinen."
|
||||
},
|
||||
"zwave": {
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
@ -1359,7 +1369,7 @@
|
||||
"false": "Epätosi",
|
||||
"header": "Solmun määritysasetukset",
|
||||
"seconds": "sekuntia",
|
||||
"set_config_parameter": "Aseta asetusparametri",
|
||||
"set_config_parameter": "Aseta parametri",
|
||||
"set_wakeup": "Aseta herätysväli",
|
||||
"true": "Tosi"
|
||||
},
|
||||
@ -1447,6 +1457,9 @@
|
||||
"showing_entries": "Näytetään kirjaukset ajalta"
|
||||
},
|
||||
"lovelace": {
|
||||
"add_entities": {
|
||||
"saving_failed": "Lovelacen käyttöliittymän asetusten tallennus epäonnistui."
|
||||
},
|
||||
"cards": {
|
||||
"confirm_delete": "Oletko varma, että haluat poistaa tämän kortin?",
|
||||
"empty_state": {
|
||||
@ -1620,6 +1633,9 @@
|
||||
"confirm_remove_config_text": "Lovelace käyttöliittymän näkymät luodaan automaattisesti alueistasi ja laitteistasi, jos poistat nykyisen määrityksen.",
|
||||
"confirm_remove_config_title": "Haluatko varmasti poistaa Lovelace-käyttöliittymän asetukset? Lovelace käyttöliittymän asetukset luodaan automaattisesti alueistasi ja laitteistasi.",
|
||||
"confirm_unsaved_changes": "Sinulla on tallentamattomia muutoksia. Haluatko varmasti poistua?",
|
||||
"confirm_unsaved_comments": "Asetuksesi sisältää kommentoituja rivejä. Kommentoituja rivejä ei tallenneta. Haluatko jatkaa?",
|
||||
"error_invalid_config": "Asetuksesi ovat virheelliset: {error}",
|
||||
"error_remove": "Asetusta ei voida poistaa: {error}",
|
||||
"header": "Muokkaa asetuksia",
|
||||
"save": "Tallenna",
|
||||
"saved": "Tallennettu",
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Si désactivé, les nouvelles entités découvertes pour {integration} ne seront pas ajoutées automatiquement à Home Assistant.",
|
||||
"enable_new_entities_label": "Activer les entités nouvellement ajoutées.",
|
||||
"title": "Options système pour {integration}"
|
||||
"title": "Options système pour {integration}",
|
||||
"update": "Mise à jour"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Annuler",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Fermer la fenêtre de dialogue",
|
||||
"edit": "Modifier l'entité",
|
||||
"person": {
|
||||
"create_zone": "Créer une zone à partir de l'emplacement actuel"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Voulez-vous vraiment supprimer cette entité ?",
|
||||
"confirm_remove_title": "Supprimer l'entité ?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instructions de mise à jour"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Nettoyer Endroit",
|
||||
"commands": "Commandes d'aspirateur :",
|
||||
"fan_speed": "Vitesse ventilateur",
|
||||
"locate": "Localiser",
|
||||
"pause": "Pause",
|
||||
"return_home": "Rentrer à la maison",
|
||||
"start": "Démarrer",
|
||||
"start_pause": "Démarrer/Pause",
|
||||
"status": "Statut",
|
||||
"stop": "Arrêter"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Modifier avec l'interface utilisateur",
|
||||
"edit_yaml": "Modifier en tant que YAML",
|
||||
"enable_disable": "Activer/Désactiver l'automatisation",
|
||||
"introduction": "Utilisez les automatisations pour donner vie à votre maison",
|
||||
"load_error_not_editable": "Seules les automations dans automations.yaml sont modifiables.",
|
||||
"load_error_unknown": "Erreur lors du chargement de l'automation ( {err_no} ).",
|
||||
@ -1870,7 +1887,7 @@
|
||||
"lovelace": {
|
||||
"add_entities": {
|
||||
"generated_unsupported": "Vous ne pouvez utiliser cette fonction que lorsque vous avez pris le contrôle de Lovelace UI.",
|
||||
"saving_failed": "La sauvegarde de la configuration de Lovelace UI a échouée.",
|
||||
"saving_failed": "La sauvegarde de la configuration de Lovelace UI a échoué.",
|
||||
"yaml_unsupported": "Vous ne pouvez pas utiliser cette fonction lorsque vous utilisé Lovelace UI en mode YAML."
|
||||
},
|
||||
"cards": {
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "États disponibles",
|
||||
"name": "Panneau d'alarme"
|
||||
},
|
||||
"button": {
|
||||
"name": "Bouton"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Conditionnel"
|
||||
},
|
||||
|
@ -309,6 +309,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"language": {
|
||||
"link_promo": "अनुवाद करने में सहायता करें"
|
||||
}
|
||||
},
|
||||
"shopping-list": {
|
||||
"add_item": "आइटम जोड़ें",
|
||||
"microphone_tip": "ऊपर दाईं ओर माइक्रोफ़ोन टैप करें और \"मेरी खरीदारी सूची में कैंडी जोड़ें\" कहें"
|
||||
|
@ -359,7 +359,7 @@
|
||||
"idle": "Tétlen",
|
||||
"off": "Ki",
|
||||
"on": "Be",
|
||||
"paused": "Felfüggesztve",
|
||||
"paused": "Szüneteltetve",
|
||||
"returning": "Dokkolás folyamatban"
|
||||
},
|
||||
"weather": {
|
||||
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Ha le van tiltva, akkor az újonnan felfedezett {integration} entitások nem lesznek automatikusan hozzáadva a Home Assistant-hoz.",
|
||||
"enable_new_entities_label": "Újonnan hozzáadott entitások engedélyezése.",
|
||||
"title": "{integration} rendszerbeállításai"
|
||||
"title": "{integration} rendszerbeállításai",
|
||||
"update": "Frissítés"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Mégse",
|
||||
@ -629,7 +630,7 @@
|
||||
"unavailable": "Ez az entitás jelenleg nem elérhető.",
|
||||
"update": "FRISSÍTÉS"
|
||||
},
|
||||
"related": "Kapcsolódás",
|
||||
"related": "Kapcsolatok",
|
||||
"settings": "Beállítások"
|
||||
},
|
||||
"generic": {
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Párbeszédpanel elvetése",
|
||||
"edit": "Entitás szerkesztése",
|
||||
"person": {
|
||||
"create_zone": "Zóna létrehozása az aktuális helyről"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Biztosan el szeretnéd távolítani ezt az entitást?",
|
||||
"confirm_remove_title": "Eltávolítod az entitást?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Frissítési Instrukciók"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Helyi takarítás",
|
||||
"commands": "Porszívó parancsok:",
|
||||
"fan_speed": "Szívóerő",
|
||||
"locate": "Keresés",
|
||||
"pause": "Szünet",
|
||||
"return_home": "Hazatérés",
|
||||
"start": "Indítás",
|
||||
"start_pause": "Indítás/szünet",
|
||||
"status": "Állapot",
|
||||
"stop": "Leállítás"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Szerkesztés a felhasználói felületen",
|
||||
"edit_yaml": "Szerkesztés YAML-ként",
|
||||
"enable_disable": "Automatizálás engedélyezése/letiltása",
|
||||
"introduction": "Használj automatizálásokat otthonod életre keltéséhez",
|
||||
"load_error_not_editable": "Csak az automations.yaml fájlban megadott automatizálások szerkeszthetők.",
|
||||
"load_error_unknown": "Hiba az automatizálás betöltésekor ({err_no}).",
|
||||
@ -1112,7 +1129,7 @@
|
||||
"forgot_password": "elfelejtett jelszó?",
|
||||
"introduction": "A Home Assistant Felhő biztonságos távoli kapcsolatot nyújt a példányodhoz, miközben távol vagy. Azt is lehetővé teszi, hogy csak felhőn alapuló szolgáltatásokhoz csatlakozz: Amazon Alexa, Google Asszisztens.",
|
||||
"introduction2": "Ezt a szolgáltatást partnerünk üzemelteti, a ",
|
||||
"introduction2a": "vállalat, amelyet a Home Assistant és a Hass.io alapítói alapítottak.",
|
||||
"introduction2a": "vállalat, amelyet a Home Assistant és a Hass.io alapítói hoztak létre.",
|
||||
"introduction3": "A Home Assistant Felhő egy előfizetéses szolgáltatás egy hónapos ingyenes próbaverzióval. Nincs szükség fizetési információk megadására.",
|
||||
"learn_more_link": "Tudj meg többet a Home Assistant Felhőről",
|
||||
"password": "Jelszó",
|
||||
@ -1135,7 +1152,7 @@
|
||||
"information": "Hozz létre egy fiókot ahhoz, hogy elindíthasd az egy hónapos ingyenes Home Assistant Felhő próbaidőszakodat. Nincs szükség fizetési információk megadására.",
|
||||
"information2": "A próbaidőszak hozzáférést biztosít a Home Assistant Felhő minden előnyéhez, beleértve a következőket:",
|
||||
"information3": "Ezt a szolgáltatást partnerünk üzemelteti, a ",
|
||||
"information3a": "vállalat, amelyet a Home Assistant és a Hass.io alapítói alapítottak.",
|
||||
"information3a": "vállalat, amelyet a Home Assistant és a Hass.io alapítói hoztak létre.",
|
||||
"information4": "Fiók regisztrálásával elfogadod az alábbi feltételeket.",
|
||||
"link_privacy_policy": "Adatvédelmi irányelvek",
|
||||
"link_terms_conditions": "Felhasználási feltételek",
|
||||
@ -1253,7 +1270,7 @@
|
||||
"details": "Itt található minden részlet az eszközről.",
|
||||
"device_not_found": "Eszköz nem található.",
|
||||
"entities": {
|
||||
"add_entities_lovelace": "Mindet a Lovelace felületre",
|
||||
"add_entities_lovelace": "Hozzáadás a Lovelace-hez",
|
||||
"entities": "Entitások",
|
||||
"none": "Ennek az eszköznek nincsenek entitásai"
|
||||
},
|
||||
@ -1496,8 +1513,8 @@
|
||||
"automation": "Automatizálások újratöltése",
|
||||
"core": "Lokáció és testreszabások újratöltése",
|
||||
"group": "Csoportok újratöltése",
|
||||
"heading": "Konfiguráció újratöltés",
|
||||
"introduction": "A Home Assistant bizonyos részei újraindítás nélkül újratölthetőek. Az újratöltés az aktuális konfiguráció helyére betölti az újat.",
|
||||
"heading": "YAML konfiguráció újratöltése",
|
||||
"introduction": "A Home Assistant bizonyos részei újraindítás nélkül újratölthetőek. Újratöltéskor az aktuálisan betöltött YAML konfiguráció helyére betöltődik az új.",
|
||||
"person": "Személyek újratöltése",
|
||||
"scene": "Jelenetek újratöltése",
|
||||
"script": "Szkriptek újratöltése",
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Rendelkezésre álló állapotok",
|
||||
"name": "Riasztópanel"
|
||||
},
|
||||
"button": {
|
||||
"name": "Gomb"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Feltételes"
|
||||
},
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Se disabilitato, le entità appena individuate per {integration} non verranno automaticamente aggiunte a Home Assistant.",
|
||||
"enable_new_entities_label": "Abilita nuove entità aggiunte.",
|
||||
"title": "Opzioni di sistema per {integration}"
|
||||
"title": "Opzioni di sistema per {integration}",
|
||||
"update": "Aggiornamento"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Annulla",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Chiudi finestra di dialogo",
|
||||
"edit": "Modifica entità",
|
||||
"person": {
|
||||
"create_zone": "Crea zona dalla posizione corrente"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Sei sicuro di voler rimuovere questa entità?",
|
||||
"confirm_remove_title": "Rimuovere l'entità?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Istruzioni per l'aggiornamento"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Posto pulito",
|
||||
"commands": "Comandi dell'aspirapolvere:",
|
||||
"fan_speed": "Velocità della ventola",
|
||||
"locate": "Individuare",
|
||||
"pause": "Pausa",
|
||||
"return_home": "Ritorna alla base",
|
||||
"start": "Avvio",
|
||||
"start_pause": "Avvio/Pausa",
|
||||
"status": "Stato",
|
||||
"stop": "Stop"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Modifica con l'Interfaccia Utente",
|
||||
"edit_yaml": "Modifica come YAML",
|
||||
"enable_disable": "Abilitare/Disabilitare l'automazione",
|
||||
"introduction": "Usa le automazioni per dare vita alla tua casa.",
|
||||
"load_error_not_editable": "Solo le Automazioni in automations.yaml sono modificabili.",
|
||||
"load_error_unknown": "Errore durante il caricamento dell'Automazione ({err_no}).",
|
||||
@ -1496,8 +1513,8 @@
|
||||
"automation": "Ricarica le Automazioni",
|
||||
"core": "Ricarica la Posizione e le Personalizzazioni",
|
||||
"group": "Ricarica i Gruppi",
|
||||
"heading": "Aggiornamento della Configurazione",
|
||||
"introduction": "Alcune parti di Home Assistant possono essere aggiornate senza richiedere un riavvio. Premendo su Ricarica si rimuoverà la loro configurazione attuale e si caricherà la versione aggiornata.",
|
||||
"heading": "Ricarica Configurazione YAML",
|
||||
"introduction": "Alcune parti di Home Assistant possono essere ricaricate senza richiedere un riavvio. Premendo su Ricarica si rimuoverà la loro Configurazione YAML attuale e si caricherà la versione aggiornata.",
|
||||
"person": "Ricarica persone",
|
||||
"scene": "Ricarica le Scene",
|
||||
"script": "Ricarica gli Script",
|
||||
@ -1512,7 +1529,7 @@
|
||||
"stop": "Arrestare"
|
||||
},
|
||||
"validation": {
|
||||
"check_config": "Controlla la configurazione",
|
||||
"check_config": "Verifica Configurazione",
|
||||
"heading": "Convalida della configurazione",
|
||||
"introduction": "Convalidare la configurazione se di recente sono state apportate alcune modifiche alla configurazione e si desidera assicurarsi che sia tutto valido",
|
||||
"invalid": "Configurazione non valida",
|
||||
@ -1679,7 +1696,7 @@
|
||||
"name": "Nome",
|
||||
"new_zone": "Nuova zona",
|
||||
"passive": "Passivo",
|
||||
"passive_note": "Le zone passive sono nascoste nel frontend e non vengono utilizzate come posizione per i tracker dei dispositivi. Ciò è utile se si desidera utilizzarlo solo per le automazioni.",
|
||||
"passive_note": "Le zone passive sono nascoste nel frontend e non vengono utilizzate come posizione per i tracker dei dispositivi. Ciò è utile solamente se si desidera utilizzarle per le automazioni.",
|
||||
"radius": "Raggio",
|
||||
"required_error_msg": "Questo campo è obbligatorio",
|
||||
"update": "Aggiorna"
|
||||
@ -1715,7 +1732,7 @@
|
||||
"config_parameter": "Parametro di configurazione",
|
||||
"config_value": "Valore di configurazione",
|
||||
"false": "Falso",
|
||||
"header": "Opzioni di configurazione del nodo",
|
||||
"header": "Opzioni Configurazione Nodo",
|
||||
"seconds": "secondi",
|
||||
"set_config_parameter": "Imposta parametro di configurazione",
|
||||
"set_wakeup": "Imposta intervallo di riattivazione",
|
||||
@ -1731,7 +1748,7 @@
|
||||
"cancel_command": "Annulla Comando",
|
||||
"heal_network": "Testa la rete",
|
||||
"remove_node": "Rimuovi nodo",
|
||||
"save_config": "Salva configurazione",
|
||||
"save_config": "Salva Configurazione",
|
||||
"soft_reset": "Soft Reset",
|
||||
"start_network": "Avvia la rete",
|
||||
"stop_network": "Ferma la rete",
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Stati disponibili",
|
||||
"name": "Pannello di allarme"
|
||||
},
|
||||
"button": {
|
||||
"name": "Pulsante"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Condizionale"
|
||||
},
|
||||
@ -2061,8 +2081,8 @@
|
||||
},
|
||||
"migrate": {
|
||||
"header": "Configurazione incompatibile",
|
||||
"migrate": "Esporta configurazione",
|
||||
"para_migrate": "Home Assistant può aggiungere automaticamente gli ID a tutte le tue schede e visualizzazioni automaticamente premendo il pulsante \"Eporta configurazione\".",
|
||||
"migrate": "Esporta Configurazione",
|
||||
"para_migrate": "Home Assistant può aggiungere automaticamente gli ID a tutte le tue schede e viste in maniera automatica premendo il pulsante \"Esporta Configurazione\".",
|
||||
"para_no_id": "Questo elemento non ha un ID. Aggiungi un ID a questo elemento in 'ui-lovelace.yaml'."
|
||||
},
|
||||
"raw_editor": {
|
||||
@ -2072,9 +2092,9 @@
|
||||
"confirm_unsaved_comments": "La tua configurazione contiene commenti, questi non verranno salvati. Vuoi continuare?",
|
||||
"error_invalid_config": "La tua configurazione non è valida: {error}",
|
||||
"error_parse_yaml": "Impossibile analizzare YAML: {error}",
|
||||
"error_remove": "Impossibile rimuovere config: {error}",
|
||||
"error_remove": "Impossibile rimuovere la configurazione: {error}",
|
||||
"error_save_yaml": "Impossibile salvare YAML: {error}",
|
||||
"header": "Modifica le impostazioni",
|
||||
"header": "Modifica Configurazione",
|
||||
"save": "Salva",
|
||||
"saved": "Salvato",
|
||||
"unsaved_changes": "Modifiche non salvate"
|
||||
@ -2196,7 +2216,7 @@
|
||||
"data": {
|
||||
"password": "Password API"
|
||||
},
|
||||
"description": "Inserisci l'API password nella configurazione http:"
|
||||
"description": "Inserire la password API nella configurazione HTTP:"
|
||||
},
|
||||
"mfa": {
|
||||
"data": {
|
||||
|
@ -31,7 +31,7 @@
|
||||
"homeassistant": "Home Assistant",
|
||||
"image_processing": "이미지처리",
|
||||
"input_boolean": "논리입력",
|
||||
"input_datetime": "날짜/시간입력",
|
||||
"input_datetime": "날짜 / 시간입력",
|
||||
"input_number": "숫자입력",
|
||||
"input_select": "선택입력",
|
||||
"input_text": "문자입력",
|
||||
@ -576,13 +576,13 @@
|
||||
},
|
||||
"related-items": {
|
||||
"area": "영역",
|
||||
"automation": "다음 자동화의 일부",
|
||||
"automation": "관련된 자동화",
|
||||
"device": "기기",
|
||||
"entity": "관련된 구성요소",
|
||||
"group": "다음 그룹의 일부",
|
||||
"group": "관련된 그룹",
|
||||
"integration": "통합 구성요소",
|
||||
"scene": "다음 씬의 일부",
|
||||
"script": "다음 스크립트의 일부"
|
||||
"scene": "관련된 씬",
|
||||
"script": "관련된 스크립트"
|
||||
},
|
||||
"relative_time": {
|
||||
"duration": {
|
||||
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "비활성화한 경우 새로 발견된 {integration} 구성요소는 Home Assistant 에 자동으로 추가되지 않습니다.",
|
||||
"enable_new_entities_label": "새로 추가된 구성요소를 활성화합니다.",
|
||||
"title": "{integration} 시스템 옵션"
|
||||
"title": "{integration} 시스템 옵션",
|
||||
"update": "업데이트"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "취소",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "대화창 닫기",
|
||||
"edit": "구성요소 편집",
|
||||
"person": {
|
||||
"create_zone": "현재 위치로 지역 만들기"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "이 구성요소를 제거하시겠습니까?",
|
||||
"confirm_remove_title": "구성요소를 제거하시겠습니까?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "업데이트 방법"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "부분 청소",
|
||||
"commands": "청소기 조작 명령:",
|
||||
"fan_speed": "팬 속도",
|
||||
"locate": "위치 이동",
|
||||
"pause": "일시정지",
|
||||
"return_home": "충전 복귀",
|
||||
"start": "시작",
|
||||
"start_pause": "시작 / 일시정지",
|
||||
"status": "상태",
|
||||
"stop": "중지"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "UI 로 편집",
|
||||
"edit_yaml": "YAML 로 편집",
|
||||
"enable_disable": "자동화 활성화 / 비활성화",
|
||||
"introduction": "자동화를 사용하여 집에 생기를 불어넣으세요",
|
||||
"load_error_not_editable": "automations.yaml 의 자동화만 편집할 수 있습니다.",
|
||||
"load_error_unknown": "자동화를 읽어오는 도중 오류가 발생했습니다 ({err_no}).",
|
||||
@ -889,7 +906,7 @@
|
||||
"delete_confirm": "정말 삭제하시겠습니까?",
|
||||
"duplicate": "복제",
|
||||
"header": "트리거",
|
||||
"introduction": "트리거는 자동화 규칙을 처리하는 시작점 입니다. 같은 자동화 규칙에 여러 개의 트리거를 지정할 수 있습니다. 트리거가 발동되면 Home Assistant 는 조건을 확인하고 동작을 호출합니다.",
|
||||
"introduction": "트리거는 자동화 규칙을 처리하는 시작점입니다. 같은 자동화 규칙에 여러 개의 트리거를 지정할 수 있습니다. 트리거가 발동되면 Home Assistant 는 조건을 확인하고 동작을 호출합니다.",
|
||||
"learn_more": "트리거에 대해 더 알아보기",
|
||||
"name": "트리거",
|
||||
"type_select": "트리거 유형",
|
||||
@ -993,7 +1010,7 @@
|
||||
"cloud": {
|
||||
"account": {
|
||||
"alexa": {
|
||||
"config_documentation": "설정 문서 보기",
|
||||
"config_documentation": "구성 문서",
|
||||
"disable": "비활성화",
|
||||
"enable": "활성화",
|
||||
"enable_ha_skill": "Alexa 에 Home Assistant 스킬 사용하기",
|
||||
@ -1010,7 +1027,7 @@
|
||||
"connection_status": "클라우드 연결 상태",
|
||||
"fetching_subscription": "구독 정보를 가져오는 중…",
|
||||
"google": {
|
||||
"config_documentation": "설정 문서 보기",
|
||||
"config_documentation": "구성 문서",
|
||||
"devices_pin": "보안 기기 PIN",
|
||||
"enable_ha_skill": "Google 어시스턴트에 Home Assistant 스킬 사용하기",
|
||||
"enable_state_reporting": "상태 보고 활성화",
|
||||
@ -1407,7 +1424,7 @@
|
||||
"create": "만들기",
|
||||
"delete": "삭제",
|
||||
"device_tracker_intro": "이 구성원에게 속한 기기를 선택해주세요.",
|
||||
"device_tracker_pick": "추적 할 기기 선택",
|
||||
"device_tracker_pick": "추적 대상 기기 선택",
|
||||
"device_tracker_picked": "추적 대상 기기",
|
||||
"link_integrations_page": "통합 구성요소 페이지",
|
||||
"link_presence_detection_integrations": "재실 감지 통합 구성요소",
|
||||
@ -1418,7 +1435,7 @@
|
||||
"no_device_tracker_available_intro": "구성원의 재실 여부를 알려주는 기기가 있다면 구성원을 해당 기기에 할당할 수 있습니다. 통합 구성요소 페이지에서 재실 감지 통합 구성요소를 추가해서 기기를 구성해보세요.",
|
||||
"update": "업데이트"
|
||||
},
|
||||
"introduction": "Home Assistant 에서 추적 할 구성원을 정의 할 수 있습니다.",
|
||||
"introduction": "Home Assistant 에서 추적할 구성원을 정의할 수 있습니다.",
|
||||
"no_persons_created_yet": "아직 생성된 구성원이 없는 것 같습니다.",
|
||||
"note_about_persons_configured_in_yaml": "참고: configuration.yaml 에서 구성된 구성원은 UI 에서 편집 할 수 없습니다."
|
||||
},
|
||||
@ -1496,8 +1513,8 @@
|
||||
"automation": "자동화 새로고침",
|
||||
"core": "위치 및 사용자화 새로고침",
|
||||
"group": "그룹 새로고침",
|
||||
"heading": "구성 내용 새로고침",
|
||||
"introduction": "Home Assistant 의 일부 구성 내용은 재시작 없이 다시 읽어들일 수 있습니다. 새로고침을 누르면 현재 구성 내용을 내리고 새로운 구성 내용을 읽어들입니다.",
|
||||
"heading": "YAML 구성 다시 읽어오기",
|
||||
"introduction": "Home Assistant 의 일부 구성 내용은 재시작 없이 다시 읽어 들일 수 있습니다. 새로고침을 누르면 현재 사용 중인 YAML 구성 내용을 내리고 새로운 구성 내용을 읽어 들입니다.",
|
||||
"person": "구성원 새로고침",
|
||||
"scene": "씬 다시읽기",
|
||||
"script": "스크립트 새로고침",
|
||||
@ -1731,7 +1748,7 @@
|
||||
"cancel_command": "명령 취소",
|
||||
"heal_network": "네트워크 새로고침",
|
||||
"remove_node": "노드 제거",
|
||||
"save_config": "설정 저장",
|
||||
"save_config": "구성 저장",
|
||||
"soft_reset": "소프트 리셋",
|
||||
"start_network": "네트워크 시작",
|
||||
"stop_network": "네트워크 중지",
|
||||
@ -1877,7 +1894,7 @@
|
||||
"confirm_delete": "이 카드를 삭제하시겠습니까?",
|
||||
"empty_state": {
|
||||
"go_to_integrations_page": "통합 페이지로 이동하기.",
|
||||
"no_devices": "이 페이지에서 기기를 제어 할 수 있지만, 기기가 아직 설정되지 않은 것 같습니다. 시작하려면 통합 페이지로 이동해주세요.",
|
||||
"no_devices": "이 페이지에서 기기를 제어할 수 있지만, 기기가 아직 설정되지 않은 것 같습니다. 시작하려면 통합 페이지로 이동해주세요.",
|
||||
"title": "집에 오신 것을 환영합니다"
|
||||
},
|
||||
"entities": {
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "사용 가능한 상태요소",
|
||||
"name": "알람 패널"
|
||||
},
|
||||
"button": {
|
||||
"name": "버튼"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "조건부"
|
||||
},
|
||||
@ -2061,8 +2081,8 @@
|
||||
},
|
||||
"migrate": {
|
||||
"header": "구성 내용이 호환되지 않습니다",
|
||||
"migrate": "설정 마이그레이션",
|
||||
"para_migrate": "Home Assistant 는 '설정 마이그레이션' 버튼을 눌러 자동으로 모든 카드와 보기에 ID를 추가 할 수 있습니다.",
|
||||
"migrate": "구성 마이그레이션",
|
||||
"para_migrate": "Home Assistant 는 '구성 마이그레이션' 버튼을 눌러 자동으로 모든 카드와 뷰에 ID를 추가할 수 있습니다.",
|
||||
"para_no_id": "이 구성요소에는 ID가 없습니다. 'ui-lovelace.yaml' 에 구성요소의 ID를 추가해주세요."
|
||||
},
|
||||
"raw_editor": {
|
||||
@ -2196,7 +2216,7 @@
|
||||
"data": {
|
||||
"password": "API 비밀번호"
|
||||
},
|
||||
"description": "configuration.yaml 에 설정한 api_password 를 입력해주세요:"
|
||||
"description": "HTTP 구성에 API 비밀번호를 입력해주세요:"
|
||||
},
|
||||
"mfa": {
|
||||
"data": {
|
||||
@ -2304,7 +2324,7 @@
|
||||
},
|
||||
"profile": {
|
||||
"advanced_mode": {
|
||||
"description": "Home Assistant 의 고급 기능과 옵션은 기본적으로 숨겨져 있으며 토글을 활성화하여 이러한 기능을 사용하실 수 있습니다. 이 설정은 사용자별 설정이며 Home Assistant 를 사용하는 다른 사용자에게 영향을 미치지 않습니다.",
|
||||
"description": "고급 기능을 활성화합니다.",
|
||||
"link_promo": "더 알아보기",
|
||||
"title": "고급 모드"
|
||||
},
|
||||
@ -2321,7 +2341,7 @@
|
||||
"description": "모바일 환경과 마찬가지로 기본적으로 사이드 바가 숨겨집니다.",
|
||||
"header": "항상 사이드바 숨기기"
|
||||
},
|
||||
"is_owner": "관리자 계정 입니다.",
|
||||
"is_owner": "관리자 계정입니다.",
|
||||
"language": {
|
||||
"dropdown_label": "언어",
|
||||
"header": "언어",
|
||||
@ -2384,7 +2404,7 @@
|
||||
"link_promo": "테마에 대해 더 알아보기"
|
||||
},
|
||||
"vibrate": {
|
||||
"description": "기기를 제어 할 때 이 기기에서 진동을 활성화 또는 비활성화합니다.",
|
||||
"description": "기기를 제어할 때 이 기기에서 진동을 활성화 또는 비활성화합니다.",
|
||||
"header": "진동효과"
|
||||
}
|
||||
},
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Falls desaktivéiert, ginn nei entdeckten Entitéiten net automatesch zu Home Assistant dobäigesat.",
|
||||
"enable_new_entities_label": "Aktivéiert nei dobäigesate Entitéiten.",
|
||||
"title": "System Optiounen"
|
||||
"title": "System Optiounen",
|
||||
"update": "Aktualiséieren"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Ofbriechen",
|
||||
@ -659,6 +660,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instruktioune fir d'Mise à jour"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Plaz botzen",
|
||||
"commands": "Staubsauger Kommandoen:",
|
||||
"fan_speed": "Vitesse vum Ventilator",
|
||||
"locate": "Lokaliséieren",
|
||||
"pause": "Pause",
|
||||
"return_home": "Zeréck zur Statioun",
|
||||
"start": "Start",
|
||||
"start_pause": "Start/Pause",
|
||||
"status": "Status",
|
||||
"stop": "Stop"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Hvis den er deaktivert, blir ikke nyoppdagede entiteter for {integration} automatisk lagt til i Home Assistant.",
|
||||
"enable_new_entities_label": "Aktiver enheter som nylig er lagt til.",
|
||||
"title": "Systemalternativer for {integration}"
|
||||
"title": "Systemalternativer for {integration}",
|
||||
"update": "Oppdater"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Avbryt",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Avvis dialogboksen",
|
||||
"edit": "Redigér entitet",
|
||||
"person": {
|
||||
"create_zone": "Opprett sone fra gjeldende plassering"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Er du sikker på at du vil fjerne denne entiteten?",
|
||||
"confirm_remove_title": "Vil du fjerne entiteten?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Oppdateringsanvisning"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Rent sted",
|
||||
"commands": "Støvsugerkommandoer:",
|
||||
"fan_speed": "Viftehastighet",
|
||||
"locate": "Lokaliser",
|
||||
"pause": "Pause",
|
||||
"return_home": "Vende hjem",
|
||||
"start": "Start",
|
||||
"start_pause": "Start / Pause",
|
||||
"status": "Status",
|
||||
"stop": "Stopp"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Rediger med UI",
|
||||
"edit_yaml": "Rediger som YAML",
|
||||
"enable_disable": "Aktivere/deaktivere automatisering",
|
||||
"introduction": "Bruk automasjon for å få liv i hjemmet ditt",
|
||||
"load_error_not_editable": "Kun automasjoner i automations.yaml kan redigeres.",
|
||||
"load_error_unknown": "Feil ved lasting av automasjon ({err_no}).",
|
||||
@ -1496,7 +1513,7 @@
|
||||
"automation": "Last inn automasjoner på nytt",
|
||||
"core": "Last inn lokasjon og spesialtilpassinger på nytt",
|
||||
"group": "Last inn grupper på nytt",
|
||||
"heading": "Konfigurasjon lastes på nytt",
|
||||
"heading": "YAML -Konfigurasjon lastes 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.",
|
||||
"person": "Last inn personer på nytt",
|
||||
"scene": "Last inn scener på nytt",
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Tilgjengelige tilstander",
|
||||
"name": "Alarmpanel"
|
||||
},
|
||||
"button": {
|
||||
"name": "Knapp"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Betinget"
|
||||
},
|
||||
|
@ -602,9 +602,10 @@
|
||||
},
|
||||
"dialogs": {
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Indien uitgeschakeld dan worden nieuwe entiteiten van {integration} niet automatisch aan Home Assistant toegevoegd.",
|
||||
"enable_new_entities_description": "Indien uitgeschakeld, worden nieuwe entiteiten van {integration} niet automatisch aan Home Assistant toegevoegd.",
|
||||
"enable_new_entities_label": "Voeg nieuwe entiteiten automatisch toe",
|
||||
"title": "Systeeminstellingen voor {integratie}"
|
||||
"title": "Systeeminstellingen voor {integration}",
|
||||
"update": "Bijwerken"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Annuleren",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Dialoogvenster sluiten",
|
||||
"edit": "Entiteit bewerken",
|
||||
"person": {
|
||||
"create_zone": "Creëer zone van huidige locatie"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Weet u zeker dat u dit item wilt verwijderen?",
|
||||
"confirm_remove_title": "Entiteit verwijderen?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Update-instructies"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Plek schoonmaken",
|
||||
"commands": "Stofzuigeropdrachten:",
|
||||
"fan_speed": "Ventilatiesnelheid",
|
||||
"locate": "Zoek",
|
||||
"pause": "Pauze",
|
||||
"return_home": "Terugkeren",
|
||||
"start": "Start",
|
||||
"start_pause": "Start/Pauze",
|
||||
"status": "Status",
|
||||
"stop": "Stop"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Bewerken met UI",
|
||||
"edit_yaml": "Bewerken als YAML",
|
||||
"enable_disable": "Schakel automatisering in/uit",
|
||||
"introduction": "Gebruik automatiseringen om je huis tot leven te brengen.",
|
||||
"load_error_not_editable": "Alleen automatiseringen in automations.yaml kunnen worden bewerkt.",
|
||||
"load_error_unknown": "Fout bij laden van automatisering ({err_no}).",
|
||||
@ -1306,7 +1323,7 @@
|
||||
"filter": {
|
||||
"filter": "filter",
|
||||
"show_disabled": "Uitgeschakelde entiteiten weergeven",
|
||||
"show_unavailable": "Uitgeschakelde entiteiten weergeven"
|
||||
"show_unavailable": "Onbeschikbare entiteiten weergeven"
|
||||
},
|
||||
"header": "Entiteiten",
|
||||
"headers": {
|
||||
@ -1339,7 +1356,7 @@
|
||||
"caption": "Integraties",
|
||||
"config_entry": {
|
||||
"area": "In {area}",
|
||||
"delete_button": "Verwijder {integratie}.",
|
||||
"delete_button": "Verwijder {integration}.",
|
||||
"delete_confirm": "Weet je zeker dat je deze integratie wilt verwijderen?",
|
||||
"device_unavailable": "apparaat niet beschikbaar",
|
||||
"entity_unavailable": "entiteit niet beschikbaar",
|
||||
@ -1351,7 +1368,7 @@
|
||||
"no_devices": "Deze integratie heeft geen apparaten.",
|
||||
"restart_confirm": "Herstart Home Assistant om het verwijderen van deze integratie te voltooien",
|
||||
"settings_button": "Instellingen bewerken voor {integration}",
|
||||
"system_options_button": "Systeeminstellingen voor {integratie}",
|
||||
"system_options_button": "Systeeminstellingen voor {integration}",
|
||||
"via": "Verbonden via"
|
||||
},
|
||||
"config_flow": {
|
||||
@ -1679,12 +1696,12 @@
|
||||
"name": "Naam",
|
||||
"new_zone": "Nieuwe zone",
|
||||
"passive": "Passief",
|
||||
"passive_note": "Passieve zones zijn verborgen in het frontend en worden niet gebruikt als locaties voor apparaat trackers. Dit is handig als je de zone wilt gebruiken voor automatiseringen.",
|
||||
"passive_note": "Passieve zones zijn verborgen in het frontend en worden niet gebruikt als locaties voor apparaattrackers. Dit is handig als je de zone wilt gebruiken voor automatiseringen.",
|
||||
"radius": "Straal",
|
||||
"required_error_msg": "Dit veld is verplicht",
|
||||
"update": "Bijwerken"
|
||||
},
|
||||
"edit_home_zone": "De locatie van je huis kan worden gewijzigd bij de algemene configuratie",
|
||||
"edit_home_zone": "De locatie van je huis kan worden gewijzigd bij de algemene instellingen.",
|
||||
"introduction": "Met zones kunt u bepaalde regio's op aarde opgeven. Wanneer een persoon zich in een zone bevindt, dan wordt de staat de naam uit de zone. Zones kunnen ook worden gebruikt als trigger of voorwaarde in automatiseringen.",
|
||||
"no_zones_created_yet": "Het lijkt erop dat je nog geen zones hebt aangemaakt."
|
||||
},
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Beschikbare statussen",
|
||||
"name": "Alarm paneel"
|
||||
},
|
||||
"button": {
|
||||
"name": "Knop"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Conditioneel"
|
||||
},
|
||||
@ -2057,7 +2077,7 @@
|
||||
"header": "Bewerk UI",
|
||||
"menu": {
|
||||
"open": "Open het Lovelace-menu",
|
||||
"raw_editor": "Platte configuratie-editor"
|
||||
"raw_editor": "Ruwe configuratie-editor"
|
||||
},
|
||||
"migrate": {
|
||||
"header": "Configuratie incompatibel",
|
||||
@ -2069,7 +2089,7 @@
|
||||
"confirm_remove_config_text": "We zullen je Lovelace gebruikersinterface automatisch genereren met je gebieden en apparaten als je de huidige Lovelace gebruikersinterface verwijdert.",
|
||||
"confirm_remove_config_title": "Weet je zeker dat je de huidige Lovelace gebruikersinterface wilt verwijderen? We zullen automatisch een nieuwe Lovelace gebruikersinterface genereren op basis van je gebieden en apparaten.",
|
||||
"confirm_unsaved_changes": "Er zijn nog niet-opgeslagen wijzigingen, weet u zeker dat u wilt afsluiten?",
|
||||
"confirm_unsaved_comments": "Uw configuratie bevat commentaren, deze worden niet opgeslagen. Wil je doorgaan?",
|
||||
"confirm_unsaved_comments": "Uw configuratie bevat opmerkingen, deze worden niet opgeslagen. Wil je doorgaan?",
|
||||
"error_invalid_config": "Uw configuratie is niet geldig: {error}",
|
||||
"error_parse_yaml": "Kan YAML niet parseren: {error}",
|
||||
"error_remove": "Kan configuratie niet verwijderen: {error}",
|
||||
|
@ -464,6 +464,9 @@
|
||||
"script": {
|
||||
"execute": "Utfør"
|
||||
},
|
||||
"service": {
|
||||
"run": "Køyr"
|
||||
},
|
||||
"timer": {
|
||||
"actions": {
|
||||
"cancel": "avbryt",
|
||||
@ -524,8 +527,22 @@
|
||||
"successfully_saved": "Vellukka lagring"
|
||||
},
|
||||
"components": {
|
||||
"area-picker": {
|
||||
"add_dialog": {
|
||||
"add": "Legg til",
|
||||
"failed_create_area": "Klarte ikkje å opprette område.",
|
||||
"name": "Namn",
|
||||
"text": "Legg til namnet til det nye området.",
|
||||
"title": "Legg til nytt område "
|
||||
},
|
||||
"add_new": "Legg til nytt område...",
|
||||
"area": "Område",
|
||||
"clear": "Klar ",
|
||||
"show_areas": "Vis områda"
|
||||
},
|
||||
"device-picker": {
|
||||
"device": "Enhet"
|
||||
"device": "Enhet",
|
||||
"toggle": "Veksl "
|
||||
},
|
||||
"entity": {
|
||||
"entity-picker": {
|
||||
@ -536,6 +553,11 @@
|
||||
"loading_history": "Lastar tilstandshistoria...",
|
||||
"no_history_found": "Inga tilstandshistorie funne"
|
||||
},
|
||||
"related-items": {
|
||||
"area": "Område",
|
||||
"device": "Eining",
|
||||
"integration": "Integrasjon"
|
||||
},
|
||||
"relative_time": {
|
||||
"duration": {
|
||||
"day": "{count} {count, plural,\none {dag}\nother {dagar}\n}",
|
||||
@ -556,9 +578,33 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Dersom denne er deaktivert, kjem ikkje nyoppdaga oppføringar til å bli automatisk lagt til i Home Assistant.",
|
||||
"enable_new_entities_label": "Aktiver nyleg tillagde oppføringar.",
|
||||
"title": "Systemval"
|
||||
"title": "Systemval",
|
||||
"update": "Oppdater"
|
||||
},
|
||||
"entity_registry": {
|
||||
"editor": {
|
||||
"confirm_delete": "Er du sikker på at du vil slette denne oppføringa?",
|
||||
"delete": "SLETT",
|
||||
"enabled_cause": "Deaktivert av {cause}.",
|
||||
"enabled_description": "Dekativere oppføringar kjem ikkje til å bli lagt til i Home Assistant",
|
||||
"enabled_label": "Aktiver oppføringa",
|
||||
"entity_id": "Oppførings-ID",
|
||||
"name": "Namnoverskriding",
|
||||
"note": "Merk: dette fungerer kanskje ikkje med alle integrasjonane.",
|
||||
"unavailable": "Denne eininga er for augeblinken ikkje tilgjengeleg.",
|
||||
"update": "OPPDATER"
|
||||
}
|
||||
},
|
||||
"generic": {
|
||||
"cancel": "Avbryt",
|
||||
"default_confirmation_title": "Er du sikker?",
|
||||
"ok": "OK"
|
||||
},
|
||||
"more_info_control": {
|
||||
"edit": "Rediger oppføringa",
|
||||
"person": {
|
||||
"create_zone": "Opprett sone frå gjeldande stad"
|
||||
},
|
||||
"script": {
|
||||
"last_action": "Siste handling"
|
||||
},
|
||||
@ -569,6 +615,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Oppdater instruksane"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Reingjer området",
|
||||
"commands": "Støvsugarkommandoar",
|
||||
"fan_speed": "Viftefart",
|
||||
"locate": "Lokaliser",
|
||||
"pause": "Sett på pause",
|
||||
"return_home": "Returner heim ",
|
||||
"start": "Start ",
|
||||
"start_pause": "Start/Sett på pause",
|
||||
"status": "Status",
|
||||
"stop": "Stopp "
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -585,6 +643,9 @@
|
||||
}
|
||||
},
|
||||
"zha_device_info": {
|
||||
"confirmations": {
|
||||
"remove": "Er du sikker på at du vil fjerne eininga?"
|
||||
},
|
||||
"manuf": "av {manufacturer}",
|
||||
"no_area": "Inga område",
|
||||
"services": {
|
||||
@ -739,6 +800,7 @@
|
||||
"unsupported_condition": "Ikkje støtta føresetnad: {condition}"
|
||||
},
|
||||
"default_name": "Ny automasjon",
|
||||
"enable_disable": "Aktiver/Deaktiver automasjon",
|
||||
"introduction": "Bruk automasjonar til å gi liv til heimen din",
|
||||
"load_error_not_editable": "Berre automasjonar i automations.yaml kan redigerast.",
|
||||
"load_error_unknown": "Feil ved lasting av automasjon ({err_no}).",
|
||||
@ -857,6 +919,7 @@
|
||||
"core_config": {
|
||||
"edit_requires_storage": "Redigeringsverkty deaktivert sidan konfigurasjonener lagra i configuration.yaml",
|
||||
"elevation": "Høgde",
|
||||
"elevation_feet": "fot",
|
||||
"elevation_meters": "Meter",
|
||||
"imperial_example": "Fahrenheit, pound",
|
||||
"latitude": "Breiddegrad",
|
||||
@ -907,6 +970,13 @@
|
||||
},
|
||||
"devices": {
|
||||
"area_picker_label": "Område",
|
||||
"automation": {
|
||||
"automations": "Automasjonar",
|
||||
"create": "Lag automasjon med eininga",
|
||||
"no_automations": "Ingen automasjonar",
|
||||
"no_device_automations": "Ingen tilgjenglege automasjonar for denne eininga."
|
||||
},
|
||||
"cant_edit": "Du kan berre redigere element som er laga i brukargrensesnittet.",
|
||||
"caption": "Einingar",
|
||||
"data_table": {
|
||||
"area": "Område",
|
||||
@ -915,7 +985,21 @@
|
||||
"model": "Modell"
|
||||
},
|
||||
"description": "Administrer tilkopla einingar",
|
||||
"info": "Enhetsinformasjon"
|
||||
"info": "Enhetsinformasjon",
|
||||
"name": "Namn",
|
||||
"scene": {
|
||||
"create": "Lag ei scene med denne eininga",
|
||||
"no_scenes": "Ingen scener",
|
||||
"scenes": "Scener"
|
||||
},
|
||||
"scenes": "Scener",
|
||||
"script": {
|
||||
"create": "Lag skript med eininga",
|
||||
"no_scripts": "Ingen skript ",
|
||||
"scripts": "Skript "
|
||||
},
|
||||
"scripts": "Skript ",
|
||||
"update": "Oppdater"
|
||||
},
|
||||
"entities": {
|
||||
"caption": "Oppføringsregister",
|
||||
@ -955,6 +1039,7 @@
|
||||
},
|
||||
"config_flow": {
|
||||
"close": "Lukk",
|
||||
"dismiss": "Avvis dialogboksa",
|
||||
"external_step": {
|
||||
"description": "Ei ekstern nettside må besøkast for å fullføre dette steget.",
|
||||
"open_site": "Opne nettside"
|
||||
@ -1042,19 +1127,57 @@
|
||||
"header": "ZigBee heimeautomasjon - Legg til eining",
|
||||
"spinner": "Leitar etter ZHA Zigbee-apparat..."
|
||||
},
|
||||
"add": {
|
||||
"caption": "Legg til eining ",
|
||||
"description": "Legg til eining i Zigbee-nettverket"
|
||||
},
|
||||
"caption": "ZHA",
|
||||
"clusters": {
|
||||
"header": "Klynger",
|
||||
"introduction": "Klynger er byggesteinane for Zigbee-funksjonaliteten. Dei sepererar funksjonaliteten i logiske einingar. Det er klient- og servertyper, som består av attributtar og kommandoar."
|
||||
},
|
||||
"description": "Zigbee heimeautomasjon nettverksadministrering",
|
||||
"device_card": {
|
||||
"area_picker_label": "Område",
|
||||
"device_name_placeholder": "Brukarnamn",
|
||||
"update_name_button": "Oppdater namn"
|
||||
},
|
||||
"devices": {
|
||||
"header": "Zigbee Home Automation - Eininga"
|
||||
},
|
||||
"group_binding": {
|
||||
"bind_button_help": "Huk den merka gruppa til den merka einingsklynga.",
|
||||
"bind_button_label": "Huk gruppa",
|
||||
"cluster_selection_help": "Vel klynga som skal bindast til den valde gruppa.",
|
||||
"group_picker_help": "Vel ei gruppe for å sende bindekommandoen til.",
|
||||
"group_picker_label": "Grupper som kan bindast",
|
||||
"header": "Gruppebinding",
|
||||
"introduction": "Huk og huk av grupper.",
|
||||
"unbind_button_help": "Huk av den merka gruppa frå den merka einingsklynga.",
|
||||
"unbind_button_label": "Huk av gruppa"
|
||||
},
|
||||
"groups": {
|
||||
"caption": "Grupper",
|
||||
"description": "Lag og modifiser Zigbee-grupper",
|
||||
"group-header": "Zigbee Home Automation - Gruppedetaljer",
|
||||
"groups-header": "Zigbee Home Automation - Gruppehandtering"
|
||||
},
|
||||
"services": {
|
||||
"reconfigure": "Konfigurer ZHA-eininga (heal device) på nytt. Bruk dette om du har problem med eininga. Dersom eining går på batteri, ver sikker på at den er vaken og tek i mot kommandar når du brukar denne tenesta.",
|
||||
"remove": "Fjern einhet frå Zigbee nettverk",
|
||||
"updateDeviceName": "Gje einheten eit eige namn i einhetsregistret."
|
||||
}
|
||||
},
|
||||
"zone": {
|
||||
"configured_in_yaml": "Sonene defingert i configuration.yaml, kan ikkje redigerast via brukargrensesnittet.",
|
||||
"detail": {
|
||||
"create": "Lag",
|
||||
"delete": "Slett",
|
||||
"required_error_msg": "Dette feltet obligatorisk",
|
||||
"update": "Oppdater"
|
||||
},
|
||||
"edit_home_zone": "Plasseringa av heimen din kan endrast i den generelle konfigurasjonen."
|
||||
},
|
||||
"zwave": {
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
@ -1144,6 +1267,9 @@
|
||||
"no_devices": "Denne sida let deg ta kontroll på einingane dine, men det ser ut til at du ikkje har sett opp noko endå. Gå til integrasjonssida for å setje i gang.",
|
||||
"title": "Velkommen heim"
|
||||
},
|
||||
"entities": {
|
||||
"never_triggered": "Aldri utløyst"
|
||||
},
|
||||
"picture-elements": {
|
||||
"call_service": "Tilkall teneste {name}",
|
||||
"hold": "Hald:",
|
||||
@ -1164,11 +1290,17 @@
|
||||
},
|
||||
"editor": {
|
||||
"card": {
|
||||
"button": {
|
||||
"name": "Knapp"
|
||||
},
|
||||
"generic": {
|
||||
"name": "Namn"
|
||||
},
|
||||
"iframe": {
|
||||
"name": "iFrame"
|
||||
},
|
||||
"shopping-list": {
|
||||
"integration_not_loaded": "Dette kortet krev at \"shopping_list\"-integrasjonen er sett opp."
|
||||
}
|
||||
},
|
||||
"edit_card": {
|
||||
@ -1408,6 +1540,9 @@
|
||||
}
|
||||
},
|
||||
"profile": {
|
||||
"advanced_mode": {
|
||||
"link_promo": "Lær meir"
|
||||
},
|
||||
"change_password": {
|
||||
"confirm_new_password": "Stadfest nytt passord",
|
||||
"current_password": "Noverande passord",
|
||||
@ -1428,6 +1563,8 @@
|
||||
"link_promo": "Hjelp å oversette"
|
||||
},
|
||||
"logout": "Logg ut",
|
||||
"logout_text": "Er du sikker på at du vil logge ut?",
|
||||
"logout_title": "Logg ut?",
|
||||
"long_lived_access_tokens": {
|
||||
"confirm_delete": "Er du sikker på at du vil slette tilgangstoken for {name}?",
|
||||
"create": "Lag token",
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Jeśli wyłączone, nowo wykryte encje nie będą automatycznie dodawane do Home Assistant'a.",
|
||||
"enable_new_entities_label": "Włącz dodawanie nowych encji.",
|
||||
"title": "Opcje systemowe dla {integration}"
|
||||
"title": "Opcje systemowe dla {integration}",
|
||||
"update": "Aktualizuj"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Anuluj",
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Zamknij okno dialogowe",
|
||||
"edit": "Edytuj encję",
|
||||
"person": {
|
||||
"create_zone": "Utwórz strefę z bieżącej lokalizacji"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Czy na pewno chcesz usunąć tę encję?",
|
||||
"confirm_remove_title": "Usunąć encję?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instrukcje aktualizacji"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Wyczyść miejsce",
|
||||
"commands": "Polecenia odkurzacza:",
|
||||
"fan_speed": "Prędkość wentylatora",
|
||||
"locate": "Zlokalizuj",
|
||||
"pause": "Pauza",
|
||||
"return_home": "Powrót do domu",
|
||||
"start": "Start",
|
||||
"start_pause": "Start/Pauza",
|
||||
"status": "Status",
|
||||
"stop": "Zatrzymaj"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Edytuj za pomocą interfejsu użytkownika",
|
||||
"edit_yaml": "Edycja jako YAML",
|
||||
"enable_disable": "Włącz/wyłącz automatyzację",
|
||||
"introduction": "Użyj automatyzacji, aby ożywić swój dom",
|
||||
"load_error_not_editable": "Tylko automatyzacje zdefiniowane w pliku automations.yaml są edytowalne.",
|
||||
"load_error_unknown": "Wystąpił błąd podczas ładowania automatyzacji ({err_no}).",
|
||||
@ -1911,6 +1928,9 @@
|
||||
"available_states": "Dostępne stany",
|
||||
"name": "Panel alarmu"
|
||||
},
|
||||
"button": {
|
||||
"name": "Przycisk"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Warunkowa"
|
||||
},
|
||||
|
@ -536,6 +536,7 @@
|
||||
},
|
||||
"common": {
|
||||
"cancel": "Cancelar",
|
||||
"close": "Fechar",
|
||||
"loading": "Carregando",
|
||||
"no": "Não",
|
||||
"save": "Salvar",
|
||||
@ -543,10 +544,24 @@
|
||||
"yes": "Sim"
|
||||
},
|
||||
"components": {
|
||||
"area-picker": {
|
||||
"add_dialog": {
|
||||
"add": "Adicionar",
|
||||
"failed_create_area": "Falha ao criar a área.",
|
||||
"name": "Nome",
|
||||
"text": "Digite o nome da nova área.",
|
||||
"title": "Adicionar nova área"
|
||||
},
|
||||
"add_new": "Adicionar nova área…",
|
||||
"area": "Área",
|
||||
"clear": "Limpar",
|
||||
"show_areas": "Mostrar áreas"
|
||||
},
|
||||
"device-picker": {
|
||||
"clear": "Limpar",
|
||||
"device": "Dispositivo",
|
||||
"show_devices": "Mostrar dispositivos"
|
||||
"show_devices": "Mostrar dispositivos",
|
||||
"toggle": "Alternar"
|
||||
},
|
||||
"entity": {
|
||||
"entity-picker": {
|
||||
@ -625,6 +640,11 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Dispensar diálogo",
|
||||
"edit": "Editar entidade",
|
||||
"restored": {
|
||||
"confirm_remove_text": "Tem certeza de que deseja remover esta entidade?",
|
||||
"confirm_remove_title": "Remover entidade?",
|
||||
"remove_action": "Remover entidade"
|
||||
},
|
||||
"script": {
|
||||
"last_action": "Última Ação",
|
||||
"last_triggered": "Último disparo"
|
||||
@ -637,6 +657,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Atualizar Instruções"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Limpar local",
|
||||
"commands": "Comandos do aspirador de pó:",
|
||||
"fan_speed": "Velocidade do ventilador",
|
||||
"locate": "Localizar",
|
||||
"pause": "Pausar",
|
||||
"return_home": "Voltar para casa",
|
||||
"start": "Iniciar",
|
||||
"start_pause": "Iniciar / Pausar",
|
||||
"status": "Estado",
|
||||
"stop": "Parar"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -1203,14 +1235,19 @@
|
||||
"actions": {
|
||||
"caption": "Quando algo é acionado ..."
|
||||
},
|
||||
"automations": "Automações",
|
||||
"conditions": {
|
||||
"caption": "Só faça alguma coisa se ..."
|
||||
},
|
||||
"create": "Crie automação com o dispositivo",
|
||||
"no_automations": "Sem automações",
|
||||
"no_device_automations": "Não há automações disponíveis para este dispositivo.",
|
||||
"triggers": {
|
||||
"caption": "Faça alguma coisa quando ..."
|
||||
}
|
||||
},
|
||||
"automations": "Automações",
|
||||
"cant_edit": "Você só pode editar itens que são criados na IU.",
|
||||
"caption": "Dispositivos",
|
||||
"confirm_rename_entity_ids": "Você também deseja renomear os IDs das entidades?",
|
||||
"data_table": {
|
||||
@ -1224,9 +1261,28 @@
|
||||
"description": "Gerenciar dispositivos conectados",
|
||||
"details": "Aqui estão todos os detalhes do seu dispositivo.",
|
||||
"device_not_found": "Dispositivo não encontrado.",
|
||||
"entities": {
|
||||
"add_entities_lovelace": "Adicionar ao Lovelace",
|
||||
"entities": "Entidades",
|
||||
"none": "Este dispositivo não possui entidades"
|
||||
},
|
||||
"info": "Informação do dispositivo",
|
||||
"name": "Nome",
|
||||
"scene": {
|
||||
"create": "Criar cenário com o dispositivo",
|
||||
"no_scenes": "Sem cenários",
|
||||
"scenes": "Cenários"
|
||||
},
|
||||
"scenes": "Cenários",
|
||||
"script": {
|
||||
"create": "Criar roteiro com o dispositivo",
|
||||
"no_scripts": "Sem roteiros",
|
||||
"scripts": "Roteiros"
|
||||
},
|
||||
"scripts": "Roteiros",
|
||||
"unknown_error": "Erro desconhecido",
|
||||
"unnamed_device": "Dispositivo sem nome"
|
||||
"unnamed_device": "Dispositivo sem nome",
|
||||
"update": "Atualizar"
|
||||
},
|
||||
"entities": {
|
||||
"caption": "Registro de Entidades",
|
||||
@ -1246,17 +1302,44 @@
|
||||
"update": "ATUALIZAR"
|
||||
},
|
||||
"picker": {
|
||||
"disable_selected": {
|
||||
"button": "Desativar selecionado",
|
||||
"confirm_text": "As entidades desativadas não serão adicionadas ao Assistente Doméstico.",
|
||||
"confirm_title": "Deseja desativar {number} entidades?"
|
||||
},
|
||||
"enable_selected": {
|
||||
"button": "Habilitar selecionado",
|
||||
"confirm_text": "Isso os disponibilizará novamente no Home Assistant se eles estiverem desativados.",
|
||||
"confirm_title": "Deseja habilitar {number} entidades?"
|
||||
},
|
||||
"filter": {
|
||||
"filter": "Filtro",
|
||||
"show_disabled": "Mostrar entidades desativadas",
|
||||
"show_unavailable": "Mostrar entidades indisponíveis"
|
||||
},
|
||||
"header": "Registro de Entidades",
|
||||
"headers": {
|
||||
"enabled": "Habilitado",
|
||||
"entity_id": "ID da entidade",
|
||||
"integration": "Integração",
|
||||
"name": "Nome"
|
||||
"name": "Nome",
|
||||
"status": "Estado"
|
||||
},
|
||||
"integrations_page": "Página de integrações",
|
||||
"introduction": "O Home Assistant mantém um registro de todas as entidades que já viu e que podem ser identificadas exclusivamente. Cada uma dessas entidades terá um ID de entidade atribuído, que será reservado apenas para essa entidade.",
|
||||
"introduction2": "Use o registro da entidade para sobrescrever o nome, alterar o ID da entidade ou remover a entrada do Home Assistant. Observe que a remoção do registro de entidade não removerá a entidade totalmente. Para fazer isso, siga o link abaixo e remova-o da página de integrações.",
|
||||
"remove_selected": {
|
||||
"button": "Remover selecionado",
|
||||
"confirm_text": "Entidades só podem ser removidas quando a integração não estiver mais fornecendo as entidades.",
|
||||
"confirm_title": "Deseja remover {number} entidades?"
|
||||
},
|
||||
"selected": "{number} selecionado",
|
||||
"show_disabled": "Mostrar entidades desativadas",
|
||||
"status": {
|
||||
"disabled": "Desativado",
|
||||
"ok": "Ok",
|
||||
"unavailable": "Indisponível"
|
||||
},
|
||||
"unavailable": "(indisponível)"
|
||||
}
|
||||
},
|
||||
@ -1544,7 +1627,8 @@
|
||||
"caption": "Grupos",
|
||||
"description": "Criar e modificar grupos Zigbee",
|
||||
"group-header": "Zigbee Home Automation - Detalhes do Grupo",
|
||||
"groups-header": "Zigbee Home Automation - Gerenciamento de grupos"
|
||||
"groups-header": "Zigbee Home Automation - Gerenciamento de grupos",
|
||||
"zha_zigbee_groups": "Grupos ZHA Zigbee"
|
||||
},
|
||||
"network_management": {
|
||||
"header": "Gerenciamento de Rede",
|
||||
|
@ -576,13 +576,19 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Se desativado, novas entidades descobertas por {integration} não serão automaticamente adicionadas ao Home Assistant.",
|
||||
"enable_new_entities_label": "Ativar novas entidades adicionadas.",
|
||||
"title": "Opções de sistema para {integration}"
|
||||
"title": "Opções de sistema para {integration}",
|
||||
"update": "Actualizar"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Cancelar",
|
||||
"ok": "",
|
||||
"title": "Tem a certeza?"
|
||||
},
|
||||
"generic": {
|
||||
"cancel": "Cancelar",
|
||||
"default_confirmation_title": "Tem a certeza?",
|
||||
"ok": "OK"
|
||||
},
|
||||
"more_info_control": {
|
||||
"script": {
|
||||
"last_action": "Última ocorrência"
|
||||
@ -594,6 +600,12 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Instruções para atualização"
|
||||
},
|
||||
"vacuum": {
|
||||
"pause": "Pausa",
|
||||
"start": "Iniciar",
|
||||
"start_pause": "Iniciar / Pausar",
|
||||
"stop": "Parar"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -1548,6 +1560,9 @@
|
||||
"available_states": "Estados Disponíveis",
|
||||
"name": "Painel de alarme"
|
||||
},
|
||||
"button": {
|
||||
"name": "Botão"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Condicional"
|
||||
},
|
||||
|
@ -625,6 +625,13 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Actualizați instrucțiunile"
|
||||
},
|
||||
"vacuum": {
|
||||
"pause": "Pauza",
|
||||
"return_home": "Návrat domov",
|
||||
"start": "Štart",
|
||||
"start_pause": "Štart/Pouza",
|
||||
"stop": "Stop"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
|
@ -492,7 +492,7 @@
|
||||
"vacuum": {
|
||||
"actions": {
|
||||
"resume_cleaning": "Продолжить уборку",
|
||||
"return_to_base": "Вернуться к док-станции",
|
||||
"return_to_base": "Вернуть к док-станции",
|
||||
"start_cleaning": "Начать уборку",
|
||||
"turn_off": "Выключить",
|
||||
"turn_on": "Включить"
|
||||
@ -604,10 +604,11 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "{integration} будет автоматически добавлять в Home Assistant вновь обнаруженные объекты",
|
||||
"enable_new_entities_label": "Добавлять новые объекты",
|
||||
"title": "{integration}"
|
||||
"title": "{integration}",
|
||||
"update": "Обновить"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Отменить",
|
||||
"cancel": "Отмена",
|
||||
"ok": "Да",
|
||||
"title": "Вы уверены?"
|
||||
},
|
||||
@ -640,6 +641,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "Закрыть диалог",
|
||||
"edit": "Изменить объект",
|
||||
"person": {
|
||||
"create_zone": "Создать зону из текущего местоположения"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Вы уверены, что хотите удалить этот объект?",
|
||||
"confirm_remove_title": "Удалить объект?",
|
||||
@ -659,6 +663,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Инструкция по обновлению"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Местная уборка",
|
||||
"commands": "Команды:",
|
||||
"fan_speed": "Мощность всасывания",
|
||||
"locate": "Найти",
|
||||
"pause": "Пауза",
|
||||
"return_home": "Вернуть к док-станции",
|
||||
"start": "Запуск",
|
||||
"start_pause": "Запуск/Пауза",
|
||||
"status": "Состояние",
|
||||
"stop": "Остановить"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -879,6 +895,7 @@
|
||||
},
|
||||
"edit_ui": "Форма ввода",
|
||||
"edit_yaml": "Текстовый редактор",
|
||||
"enable_disable": "Включение или отключение правила автоматизации",
|
||||
"introduction": "Используйте автоматизацию, чтобы оживить Ваш дом.",
|
||||
"load_error_not_editable": "Доступны для редактирования только автоматизации из automations.yaml.",
|
||||
"load_error_unknown": "Ошибка загрузки автоматизации ({err_no}).",
|
||||
@ -1496,8 +1513,8 @@
|
||||
"automation": "Перезагрузить автоматизации",
|
||||
"core": "Обновить местоположение и кастомизацию",
|
||||
"group": "Перезагрузить группы",
|
||||
"heading": "Перезагрузка конфигурации",
|
||||
"introduction": "Некоторые компоненты Home Assistant можно перезагрузить без необходимости перезапуска всей системы. Перезагрузка выгружает текущую конфигурацию и загружает новую.",
|
||||
"heading": "Перезагрузка конфигурации YAML",
|
||||
"introduction": "Некоторые компоненты Home Assistant можно перезагрузить без необходимости перезапуска всей системы. Перезагрузка выгружает текущую конфигурацию YAML и загружает новую.",
|
||||
"person": "Перезагрузить персоны",
|
||||
"scene": "Перезагрузить сцены",
|
||||
"script": "Перезагрузить сценарии",
|
||||
@ -1904,6 +1921,9 @@
|
||||
"available_states": "Доступные состояния",
|
||||
"name": "Панель сигнализации"
|
||||
},
|
||||
"button": {
|
||||
"name": "Кнопка"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Conditional"
|
||||
},
|
||||
@ -2063,7 +2083,7 @@
|
||||
"confirm_remove_config_title": "Вы уверены, что хотите очистить конфигурацию пользовательского интерфейса?",
|
||||
"confirm_unsaved_changes": "У вас есть несохраненные изменения. Вы уверены, что хотите выйти?",
|
||||
"confirm_unsaved_comments": "Ваша конфигурация содержит комментарии, они не будут сохранены. Вы хотите продолжить?",
|
||||
"error_invalid_config": "Ваша конфигурация недействительна: {error}",
|
||||
"error_invalid_config": "Конфигурация недействительна: {error}",
|
||||
"error_parse_yaml": "Ошибка при разборе синтаксиса YAML: {error}",
|
||||
"error_remove": "Не удалось удалить конфигурацию: {error}",
|
||||
"error_save_yaml": "Не удалось сохранить YAML: {error}",
|
||||
@ -2080,7 +2100,7 @@
|
||||
"save": "Получить контроль"
|
||||
},
|
||||
"suggest_card": {
|
||||
"add": "Добавить",
|
||||
"add": "Подтвердить",
|
||||
"create_own": "Изменить",
|
||||
"header": "Вариант отображения в пользовательском интерфейсе"
|
||||
},
|
||||
|
@ -478,6 +478,9 @@
|
||||
"script": {
|
||||
"execute": "Izvedi"
|
||||
},
|
||||
"service": {
|
||||
"run": "Poženi"
|
||||
},
|
||||
"timer": {
|
||||
"actions": {
|
||||
"cancel": "Prekliči",
|
||||
@ -541,10 +544,24 @@
|
||||
"yes": "Da"
|
||||
},
|
||||
"components": {
|
||||
"area-picker": {
|
||||
"add_dialog": {
|
||||
"add": "Dodaj",
|
||||
"failed_create_area": "Ni bilo mogoče ustvariti območja.",
|
||||
"name": "Ime",
|
||||
"text": "Vnesite ime novega območja.",
|
||||
"title": "Dodajte novo območje"
|
||||
},
|
||||
"add_new": "Dodaj novo območje …",
|
||||
"area": "Območje",
|
||||
"clear": "Počisti",
|
||||
"show_areas": "Pokaži cone"
|
||||
},
|
||||
"device-picker": {
|
||||
"clear": "Počisti",
|
||||
"device": "Naprava",
|
||||
"show_devices": "Pokažite naprave"
|
||||
"show_devices": "Pokažite naprave",
|
||||
"toggle": "Preklopite"
|
||||
},
|
||||
"entity": {
|
||||
"entity-picker": {
|
||||
@ -558,7 +575,14 @@
|
||||
"no_history_found": "Ni najdene zgodovine stanj."
|
||||
},
|
||||
"related-items": {
|
||||
"area": "Območje"
|
||||
"area": "Območje",
|
||||
"automation": "Del naslednjih avtomatizacij",
|
||||
"device": "Naprava",
|
||||
"entity": "Sorodne entitete",
|
||||
"group": "Del naslednjih skupin",
|
||||
"integration": "Integracija",
|
||||
"scene": "Del naslednjih prizorov",
|
||||
"script": "Del naslednjih skript"
|
||||
},
|
||||
"relative_time": {
|
||||
"duration": {
|
||||
@ -591,10 +615,31 @@
|
||||
"title": "Preklopi domene"
|
||||
},
|
||||
"entity_registry": {
|
||||
"dismiss": "Opusti"
|
||||
"control": "Nadzor",
|
||||
"dismiss": "Opusti",
|
||||
"editor": {
|
||||
"confirm_delete": "Ali ste prepričani, da želite izbrisati ta vnos?",
|
||||
"delete": "BRISANJE",
|
||||
"enabled_cause": "Onemogočeno zaradi {cause}.",
|
||||
"enabled_description": "Onemogočeni subjekti ne bodo dodani v Home Assistant-a.",
|
||||
"enabled_label": "Omogoči entiteto",
|
||||
"entity_id": "ID subjekta",
|
||||
"name": "Preglasitev imena",
|
||||
"note": "Opomba: to morda še ne deluje z vsemi integracijami.",
|
||||
"unavailable": "Ta entiteta trenutno ni na voljo.",
|
||||
"update": "POSODOBITEV"
|
||||
},
|
||||
"related": "Povezano",
|
||||
"settings": "Nastavitve"
|
||||
},
|
||||
"generic": {
|
||||
"cancel": "Prekliči",
|
||||
"default_confirmation_title": "Ste prepričani?",
|
||||
"ok": "OK"
|
||||
},
|
||||
"more_info_control": {
|
||||
"dismiss": "Opusti pogovorno okno",
|
||||
"edit": "Uredi entiteto",
|
||||
"restored": {
|
||||
"confirm_remove_text": "Ali ste prepričani, da želite odstraniti to entiteto?",
|
||||
"confirm_remove_title": "Ali želite odstraniti entiteto?",
|
||||
@ -603,7 +648,8 @@
|
||||
"remove_intro": "Če entiteta ni več v uporabi, jo lahko očistite tako, da jo odstranite."
|
||||
},
|
||||
"script": {
|
||||
"last_action": "Zadnje Dejanje"
|
||||
"last_action": "Zadnje Dejanje",
|
||||
"last_triggered": "Nazadnje sproženo"
|
||||
},
|
||||
"settings": "Nastavitve entitete",
|
||||
"sun": {
|
||||
@ -613,6 +659,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Navodila za posodabitev"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Očisti točko",
|
||||
"commands": "Ukazi sesalnika:",
|
||||
"fan_speed": "Hitrost ventilatorja",
|
||||
"locate": "Poiščite",
|
||||
"pause": "Premor",
|
||||
"return_home": "Vrni se domov",
|
||||
"start": "Zagon",
|
||||
"start_pause": "Začetek/Premor",
|
||||
"status": "Stanje",
|
||||
"stop": "Ustavi"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -643,6 +701,9 @@
|
||||
"reconfigure": "Ponovno konfigurirajte napravo",
|
||||
"remove": "Odstranite napravo"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Ali ste prepričani, da želite odstraniti napravo?"
|
||||
},
|
||||
"last_seen": "Nazadnje viden",
|
||||
"manuf": "naredil: {manufacturer}",
|
||||
"no_area": "Brez območja",
|
||||
@ -1177,14 +1238,19 @@
|
||||
"actions": {
|
||||
"caption": "Ko se nekaj sproži ..."
|
||||
},
|
||||
"automations": "Avtomatizacije",
|
||||
"conditions": {
|
||||
"caption": "Naredite nekaj, samo če ..."
|
||||
},
|
||||
"create": "Ustvarjanje avtomatizacije z napravo",
|
||||
"no_automations": "Ni avtomatizacij",
|
||||
"no_device_automations": "Za to napravo ni na voljo nobenih avtomatizacij.",
|
||||
"triggers": {
|
||||
"caption": "Naredi nekaj, ko ..."
|
||||
}
|
||||
},
|
||||
"automations": "Avtomatizacije",
|
||||
"cant_edit": "Urejate lahko samo elemente, ki so ustvarjeni v uporabniškem vmesniku.",
|
||||
"caption": "Naprave",
|
||||
"confirm_rename_entity_ids": "Ali želite preimenovati tudi ID entitete vaših entitet?",
|
||||
"data_table": {
|
||||
@ -1204,8 +1270,22 @@
|
||||
"none": "Ta naprava nima entitet"
|
||||
},
|
||||
"info": "Informacije o napravi",
|
||||
"name": "Ime",
|
||||
"scene": {
|
||||
"create": "Ustvarjanje scen z napravo",
|
||||
"no_scenes": "Ni scen",
|
||||
"scenes": "Scene"
|
||||
},
|
||||
"scenes": "Scene",
|
||||
"script": {
|
||||
"create": "Ustvarjanje skript z napravo",
|
||||
"no_scripts": "Ni skript",
|
||||
"scripts": "Skripte"
|
||||
},
|
||||
"scripts": "Skripte",
|
||||
"unknown_error": "Neznana napaka",
|
||||
"unnamed_device": "Neimenovana naprava"
|
||||
"unnamed_device": "Neimenovana naprava",
|
||||
"update": "Posodobite"
|
||||
},
|
||||
"entities": {
|
||||
"caption": "Entitete",
|
||||
@ -1218,6 +1298,8 @@
|
||||
"enabled_cause": "Onemogočeno zaradi {cause}.",
|
||||
"enabled_description": "Onemogočeni subjekti ne bodo dodani v Home Assistant-a.",
|
||||
"enabled_label": "Omogoči entiteto",
|
||||
"entity_id": "ID subjekta",
|
||||
"name": "Preglasitev imena",
|
||||
"note": "Opomba: to morda še ne deluje z vsemi integracijami.",
|
||||
"unavailable": "Ta entiteta trenutno ni na voljo.",
|
||||
"update": "POSODOBITEV"
|
||||
@ -1250,7 +1332,9 @@
|
||||
"introduction": "Home Assistant vodi register vseh entitet, ki jih je kdajkoli videl in jih je mogoče enolično identificirati. Vsak od teh entitet ima dodeljen ID entitete, ki bo rezerviran samo za to entiteto.",
|
||||
"introduction2": "Z registrom entitet preglasite ime, spremenite ID entitete ali odstranite vnos iz Home Assistent-a. Opomba, odstranitev vnosa registra entitet ne bo odstranila entitete. Če želite to narediti, sledite spodnji povezavi in jo odstranite s strani za integracijo.",
|
||||
"remove_selected": {
|
||||
"button": "Odstrani izbrane"
|
||||
"button": "Odstrani izbrane",
|
||||
"confirm_text": "Entitete je mogoče odstraniti le, če jih integracija več ne zagotavlja.",
|
||||
"confirm_title": "Ali želite odstraniti {number} entiteto-i/e?"
|
||||
},
|
||||
"selected": "{številka} izbrana/ih",
|
||||
"show_disabled": "Pokaži onemogočene subjekte",
|
||||
@ -1288,6 +1372,7 @@
|
||||
"area_picker_label": "Območje",
|
||||
"close": "Zapri",
|
||||
"created_config": "Ustvarjena konfiguracija za {name}.",
|
||||
"dismiss": "Opusti pogovorno okno",
|
||||
"error_saving_area": "Napaka pri shranjevanju območja: {error}",
|
||||
"external_step": {
|
||||
"description": "Ta korak zahteva, da za končanje obiščete zunanjo spletno stran.",
|
||||
@ -1425,8 +1510,10 @@
|
||||
"group": "Ponovno naloži skupine",
|
||||
"heading": "Ponovno nalaganje konfiguracije",
|
||||
"introduction": "Nekateri deli Home Assistanta se lahko znova naložijo brez potrebe po ponovnem zagonu. S pritiskom na \"ponovno naloži\" se bo naložila nova konfiguracija",
|
||||
"person": "Ponovno naloži osebe",
|
||||
"scene": "Ponovno naloži scene",
|
||||
"script": "Ponovno naloži skripte"
|
||||
"script": "Ponovno naloži skripte",
|
||||
"zone": "Ponovno naloži območja"
|
||||
},
|
||||
"server_management": {
|
||||
"confirm_restart": "Ali ste prepričani, da želite znova zagnati Home Assistant-a?",
|
||||
@ -1486,6 +1573,10 @@
|
||||
"search_again": "Ponovno iskanje",
|
||||
"spinner": "Iskanje ZHA Zigbee naprav..."
|
||||
},
|
||||
"add": {
|
||||
"caption": "Dodajte naprave",
|
||||
"description": "Dodajte naprave v omrežje Zigbee"
|
||||
},
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Atributi izbrane gruče",
|
||||
@ -1505,7 +1596,9 @@
|
||||
"issue_zigbee_command": "Izdajte ukaz Zigbee"
|
||||
},
|
||||
"clusters": {
|
||||
"help_cluster_dropdown": "Izberite gručo, če si želite ogledati njene atribute in ukaze."
|
||||
"header": "Gruče",
|
||||
"help_cluster_dropdown": "Izberite gručo, če si želite ogledati njene atribute in ukaze.",
|
||||
"introduction": "Gruče so sestavni del funkcionalnosti Zigbee. Funkcionalnost ločijo na logične enote. Obstajajo vrste odjemalcev in strežnikov, ki jih sestavljajo atributi in ukazi."
|
||||
},
|
||||
"common": {
|
||||
"add_devices": "Dodajte naprave",
|
||||
@ -1520,10 +1613,49 @@
|
||||
"device_name_placeholder": "Ime, ki ga je dodelil uporabnik",
|
||||
"update_name_button": "Posodobi ime"
|
||||
},
|
||||
"groups": {
|
||||
"caption": "Skupine",
|
||||
"create": "Ustvari skupino"
|
||||
"devices": {
|
||||
"header": "ZigBee Home Automation-naprava"
|
||||
},
|
||||
"group_binding": {
|
||||
"bind_button_help": "Povežite izbrano skupino z izbranimi gručami naprave.",
|
||||
"bind_button_label": "Združi skupino",
|
||||
"cluster_selection_help": "Izberite gruče, ki se vežejo na izbrano skupino.",
|
||||
"group_picker_help": "Izberite skupino, ki bo izdala ukaz vezanja.",
|
||||
"group_picker_label": "Skupine za povezovanje",
|
||||
"header": "Vezava skupin",
|
||||
"introduction": "Povežite in razvezujte skupine.",
|
||||
"unbind_button_help": "Odvežite izbrano skupino iz izbranih gruč naprav.",
|
||||
"unbind_button_label": "Razdruži skupino"
|
||||
},
|
||||
"groups": {
|
||||
"add_members": "Dodajte člane",
|
||||
"adding_members": "Dodajanje članov",
|
||||
"caption": "Skupine",
|
||||
"create": "Ustvari skupino",
|
||||
"create_group": "Zigbee Home Automation - Ustvari skupino",
|
||||
"create_group_details": "Da ustvarite novo skupino Zigbee vnesite zahtevane podrobnosti.",
|
||||
"creating_group": "Ustvarjanje skupine",
|
||||
"description": "Ustvarjajte in spreminjajte skupine Zigbee",
|
||||
"group_details": "Tu so vse podrobnosti za izbrano skupino Zigbee.",
|
||||
"group_id": "ID skupine",
|
||||
"group_info": "Informacije o skupini",
|
||||
"group_name_placeholder": "Ime skupine",
|
||||
"group_not_found": "Skupine ni mogoče najti!",
|
||||
"group-header": "Zigbee Home Automation - Podrobnosti o skupini",
|
||||
"groups": "Skupine",
|
||||
"groups-header": "ZigBee Home Automation-upravljanje skupin",
|
||||
"header": "ZigBee Home Automation-upravljanje skupin",
|
||||
"introduction": "Ustvarite in spreminjajte skupine Zigbee",
|
||||
"manage_groups": "Upravljajte zigbee skupine",
|
||||
"members": "Člani",
|
||||
"remove_groups": "Odstrani skupine",
|
||||
"remove_members": "Odstranite člane",
|
||||
"removing_groups": "Odstranjevanje skupin",
|
||||
"removing_members": "Odstranjevanje članov",
|
||||
"zha_zigbee_groups": "ZHA Zigbee Skupine"
|
||||
},
|
||||
"header": "Konfigurirajte Zigbee Home Automation",
|
||||
"introduction": "Tu je možno konfigurirati komponento ZHA. Iz uporabniškega vmesnika še ni mogoče konfigurirati vsega, vendar delamo na tem.",
|
||||
"network_management": {
|
||||
"header": "Upravljanje omrežja",
|
||||
"introduction": "Ukazi, ki vplivajo na celotno omrežje"
|
||||
@ -1539,16 +1671,34 @@
|
||||
"reconfigure": "Ponovno konfigurirajte napravo ZHA (\"pozdravite\" napravo). To uporabite, če imate z njo težave. Če ta naprava deluje na baterije, se prepričajte, da je budna in sprejema ukaze pri uporabi te storitve.",
|
||||
"remove": "Odstranite napravo iz omrežja ZigBee.",
|
||||
"updateDeviceName": "Nastavite ime po meri za to napravo v registru naprav."
|
||||
}
|
||||
},
|
||||
"title": "Zigbee Home Automation"
|
||||
},
|
||||
"zone": {
|
||||
"add_zone": "Dodaj območje",
|
||||
"caption": "Območja",
|
||||
"configured_in_yaml": "Območij, konfiguriranih prek config.yaml, ni mogoče urejati prek uporabniškega vmesnika.",
|
||||
"confirm_delete": "Ali ste prepričani, da želite izbrisati to območje?",
|
||||
"create_zone": "Ustvari območje",
|
||||
"description": "Upravljajte območja, v katerih želite slediti osebam.",
|
||||
"detail": {
|
||||
"create": "Ustvari",
|
||||
"delete": "Izbriši",
|
||||
"icon": "Ikona",
|
||||
"icon_error_msg": "Ikona mora biti v obliki predpona:ime ikone, na primer: mdi:home",
|
||||
"latitude": "Zemljepisna širina",
|
||||
"longitude": "Zemljepisna dolžina",
|
||||
"name": "Ime",
|
||||
"new_zone": "Novo območje",
|
||||
"passive": "Pasivno",
|
||||
"passive_note": "Pasivna območja so skrita v \"frontendu\" in jih ne uporabljamo za sledenje naprav. Koristna so, če jih želite uporabiti samo za avtomatizacijo.",
|
||||
"radius": "Polmer",
|
||||
"required_error_msg": "To polje je obvezno",
|
||||
"update": "Posodobite"
|
||||
}
|
||||
},
|
||||
"edit_home_zone": "Lokacijo vašega doma lahko spremenite v splošni konfiguraciji.",
|
||||
"introduction": "Območja omogočajo določitev določenih regij. Ko je oseba znotraj tega območja, bo stanje prevzelo njegovo ime. Območja se lahko uporabljajo tudi kot sprožilec ali pogoj v avtomatizacijah.",
|
||||
"no_zones_created_yet": "Izgleda, da še niste ustvarili nobenih con."
|
||||
},
|
||||
"zwave": {
|
||||
"caption": "Z-Wave",
|
||||
@ -1731,7 +1881,9 @@
|
||||
},
|
||||
"lovelace": {
|
||||
"add_entities": {
|
||||
"saving_failed": "Shranjevanje nastavitve uporabniškega vmesnika Lovelace ni uspelo."
|
||||
"generated_unsupported": "To funkcijo lahko uporabite le, ko ste prevzeli nadzor nad uporabniškim vmesnikom Lovelace.",
|
||||
"saving_failed": "Shranjevanje nastavitve uporabniškega vmesnika Lovelace ni uspelo.",
|
||||
"yaml_unsupported": "Te funkcije ne morete uporabljati pri uporabi uporabniškega vmesnika Lovelace v načinu YAML."
|
||||
},
|
||||
"cards": {
|
||||
"confirm_delete": "Ali ste prepričani, da želite izbrisati to kartico?",
|
||||
@ -1740,6 +1892,9 @@
|
||||
"no_devices": "Ta stran vam omogoča nadzor nad napravami, vendar je videti, da še niste nastavili nobenih naprav. Pojdite na stran za integracije, da začnete.",
|
||||
"title": "Dobrodošli Doma"
|
||||
},
|
||||
"entities": {
|
||||
"never_triggered": "Nikoli sprožen"
|
||||
},
|
||||
"picture-elements": {
|
||||
"call_service": "Kličite storitev {name}",
|
||||
"hold": "Pridržite:",
|
||||
@ -1870,6 +2025,7 @@
|
||||
"name": "Senzor"
|
||||
},
|
||||
"shopping-list": {
|
||||
"integration_not_loaded": "Ta kartica zahteva nastavitev integracije `shopping_list`.",
|
||||
"name": "Nakupovalni seznam"
|
||||
},
|
||||
"thermostat": {
|
||||
@ -1922,10 +2078,13 @@
|
||||
"para_no_id": "Ta element nima ID-ja. Prosimo, dodajte ID tega elementa v 'ui-lovelace.yaml'."
|
||||
},
|
||||
"raw_editor": {
|
||||
"confirm_remove_config_text": "Samodejno bomo ustvarili vaše poglede uporabniškega vmesnika Lovelace z vašimi območji in napravami, če odstranite konfiguracijo uporabniškega vmesnika Lovelace.",
|
||||
"confirm_remove_config_title": "Ali ste prepričani, da želite odstraniti konfiguracijo uporabniškega vmesnika Lovelace? Samodejno bomo ustvarili vaše poglede uporabniškega vmesnika Lovelace z vašimi območji in napravami.",
|
||||
"confirm_unsaved_changes": "Imate neshranjene spremembe, ali ste prepričani, da želite zapreti?",
|
||||
"confirm_unsaved_comments": "Vaša konfiguracija vsebuje komentarje, ti ne bodo shranjeni. Ali želite nadaljevati?",
|
||||
"error_invalid_config": "Vaš konfiguracija ni veljavna: {error}",
|
||||
"error_parse_yaml": "Ni mogoče razčleniti YAML: {error}",
|
||||
"error_remove": "Konfiguracije ni mogoče odstraniti: {error}",
|
||||
"error_save_yaml": "YAML-a ni mogoče shraniti: {error}",
|
||||
"header": "Uredi nastavitve",
|
||||
"save": "Shrani",
|
||||
@ -1941,7 +2100,8 @@
|
||||
},
|
||||
"suggest_card": {
|
||||
"add": "Dodaj v uporabniški vmesnik Lovelace",
|
||||
"create_own": "Izberite drugačno karto"
|
||||
"create_own": "Izberite drugačno karto",
|
||||
"header": "Za vas smo ustvarili predlog"
|
||||
},
|
||||
"view": {
|
||||
"panel_mode": {
|
||||
@ -2157,6 +2317,7 @@
|
||||
"profile": {
|
||||
"advanced_mode": {
|
||||
"description": "Home Assistant privzeto skrije napredne funkcije in možnosti. Do teh funkcij lahko dostopate tako, da vklopite to stikalo. To je uporabniško določena nastavitev, ki ne vpliva na druge uporabnike.",
|
||||
"link_promo": "Preberite več",
|
||||
"title": "Napredni način"
|
||||
},
|
||||
"change_password": {
|
||||
@ -2179,6 +2340,7 @@
|
||||
"link_promo": "Pomagajte pri prevodu"
|
||||
},
|
||||
"logout": "Odjava",
|
||||
"logout_text": "Ali ste prepričani, da se želite odjaviti?",
|
||||
"logout_title": "Odjava?",
|
||||
"long_lived_access_tokens": {
|
||||
"confirm_delete": "Ali ste prepričani, da želite izbrisati žeton za dostop za {name} ?",
|
||||
|
@ -604,7 +604,8 @@
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_description": "Nyupptäckta entiteter kommer ej läggas till automatiskt i Home Assistant om de är inaktiverade.",
|
||||
"enable_new_entities_label": "Aktivera nyligen tillagda enheter.",
|
||||
"title": "Systeminställningar för {integration}"
|
||||
"title": "Systeminställningar för {integration}",
|
||||
"update": "Uppdatera"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "Avbryt",
|
||||
@ -659,6 +660,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Uppdateringsanvisningar"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Rengör plats",
|
||||
"commands": "Dammsugarkommandon:",
|
||||
"fan_speed": "Fläkthastighet",
|
||||
"locate": "Lokalisera",
|
||||
"pause": "Pausa",
|
||||
"return_home": "Återvänd hem",
|
||||
"start": "Starta",
|
||||
"start_pause": "Starta/Pausa",
|
||||
"status": "Status",
|
||||
"stop": "Stoppa"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -1496,7 +1509,7 @@
|
||||
"automation": "Ladda om automationer",
|
||||
"core": "Ladda om plats & anpassningar",
|
||||
"group": "Ladda om grupper",
|
||||
"heading": "Konfigurationen laddas om",
|
||||
"heading": "YAML-konfiguration laddas om",
|
||||
"introduction": "Vissa delar av Home Assistant kan laddas om utan att en omstart krävs. Att trycka på \"ladda om\" innebär att den nuvarande konfiguration inaktiveras och den nya laddas.",
|
||||
"person": "Ladda om personer",
|
||||
"scene": "Ladda om scenarier",
|
||||
@ -1679,12 +1692,12 @@
|
||||
"name": "Namn",
|
||||
"new_zone": "Ny Zon",
|
||||
"passive": "Passiv",
|
||||
"passive_note": "Passiva zoner är dolda i frontend och används inte som plats för enhetsspårare. Detta är användbart om du bara vill använda den för automatiseringar.",
|
||||
"passive_note": "Passiva zoner är dolda i frontend och används inte som plats för enhetsspårare. Detta är användbart om du bara vill använda det för automatiseringar.",
|
||||
"radius": "Radie",
|
||||
"required_error_msg": "Det här fältet krävs",
|
||||
"update": "Uppdatera"
|
||||
},
|
||||
"edit_home_zone": "Platsen för ditt hem kan ändras i general config.",
|
||||
"edit_home_zone": "Platsen för ditt hem kan ändras i den allmänna konfigurationen.",
|
||||
"introduction": "Med zoner kan du ange vissa regioner på jorden. När en person befinner sig i en zon tar tillståndet namnet från zonen. Zoner kan också användas som utlösare eller villkor i automatiseringsinställningar.",
|
||||
"no_zones_created_yet": "Det verkar som om du inte har skapat några zoner ännu."
|
||||
},
|
||||
|
@ -59,6 +59,7 @@
|
||||
},
|
||||
"groups": {
|
||||
"system-admin": "Yöneticiler",
|
||||
"system-read-only": "Salt Okunur Kullanıcılar",
|
||||
"system-users": "Kullanıcılar"
|
||||
},
|
||||
"panel": {
|
||||
@ -366,6 +367,7 @@
|
||||
"cloudy": "Bulutlu",
|
||||
"exceptional": "Olağanüstü",
|
||||
"fog": "Sis",
|
||||
"hail": "Selam",
|
||||
"lightning": "Yıldırım",
|
||||
"lightning-rainy": "Yıldırım, yağmurlu",
|
||||
"partlycloudy": "Parçalı bulutlu",
|
||||
@ -575,7 +577,10 @@
|
||||
"automation": "Aşağıdaki otomasyonların bir parçası",
|
||||
"device": "Cihaz",
|
||||
"entity": "İlgili varlıklar",
|
||||
"integration": "Entegrasyon"
|
||||
"group": "Aşağıdaki grupların bir parçası",
|
||||
"integration": "Entegrasyon",
|
||||
"scene": "Aşağıdaki sahnelerin bir parçası",
|
||||
"script": "Aşağıdaki komut dosyalarının bir parçası"
|
||||
},
|
||||
"relative_time": {
|
||||
"duration": {
|
||||
@ -596,7 +601,8 @@
|
||||
"dialogs": {
|
||||
"config_entry_system_options": {
|
||||
"enable_new_entities_label": "Yeni eklenen varlıkları etkinleştir.",
|
||||
"title": "{integration} için Sistem Seçenekleri"
|
||||
"title": "{integration} için Sistem Seçenekleri",
|
||||
"update": "Güncelle"
|
||||
},
|
||||
"confirmation": {
|
||||
"cancel": "İptal",
|
||||
@ -617,6 +623,7 @@
|
||||
"enabled_label": "Varlığı etkinleştir",
|
||||
"entity_id": "Varlık kimliği",
|
||||
"name": "Ad Geçersiz Kılma",
|
||||
"note": "Not: bu henüz tüm entegrasyonlarla çalışmayabilir.",
|
||||
"unavailable": "Bu varlık şu anda kullanılamıyor.",
|
||||
"update": "GÜNCELLE"
|
||||
},
|
||||
@ -631,6 +638,9 @@
|
||||
"more_info_control": {
|
||||
"dismiss": "İletişim kutusunu kapat",
|
||||
"edit": "Varlığı düzenle",
|
||||
"person": {
|
||||
"create_zone": "Geçerli konumdan bölge oluşturma"
|
||||
},
|
||||
"restored": {
|
||||
"confirm_remove_text": "Bu varlığı kaldırmak istediğinizden emin misiniz?",
|
||||
"confirm_remove_title": "Varlık kaldırılsın mı?",
|
||||
@ -649,6 +659,18 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Talimatları Güncelle"
|
||||
},
|
||||
"vacuum": {
|
||||
"clean_spot": "Noktayı temizle",
|
||||
"commands": "Elektrikli süpürge komutları:",
|
||||
"fan_speed": "Pervane hızı",
|
||||
"locate": "Yeri tespit et",
|
||||
"pause": "Duraklat",
|
||||
"return_home": "Başlangıç Sayfası",
|
||||
"start": "Başlat",
|
||||
"start_pause": "Başlat/Duraklat",
|
||||
"status": "Durum",
|
||||
"stop": "Durdur"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -679,13 +701,17 @@
|
||||
"reconfigure": "Cihazı Yeniden Yapılandır",
|
||||
"remove": "Cihazı Kaldır"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Cihazı kaldırmak istediğinize emin misiniz?"
|
||||
},
|
||||
"last_seen": "Son görülen",
|
||||
"manuf": "{manufacturer} tarafından",
|
||||
"no_area": "Alan Yok",
|
||||
"power_source": "Güç kaynağı",
|
||||
"quirk": "Orijinal",
|
||||
"services": {
|
||||
"remove": "Bir cihazı Zigbee ağından kaldır."
|
||||
"remove": "Bir cihazı Zigbee ağından kaldır.",
|
||||
"updateDeviceName": "Aygıt kayıt defterinde bu aygıt için özel bir ad ayarlayın."
|
||||
},
|
||||
"unknown": "Bilinmeyen",
|
||||
"zha_device_card": {
|
||||
@ -755,6 +781,7 @@
|
||||
"delete_confirm": "Silmek istediğinize emin misiniz?",
|
||||
"duplicate": "Kopya",
|
||||
"header": "Aksiyonlar",
|
||||
"introduction": "İşlemler, otomasyon tetiklendiğinde Home Assistant'ın yapacağı işlemlerdir.",
|
||||
"learn_more": "İşlemler hakkında daha fazla bilgi edinin",
|
||||
"name": "Aksiyon",
|
||||
"type_select": "Aksiyon türü",
|
||||
@ -799,6 +826,7 @@
|
||||
"delete_confirm": "Silmek istediğinizden emin misiniz?",
|
||||
"duplicate": "Kopya",
|
||||
"header": "Koşullar",
|
||||
"introduction": "Koşullar isteğe bağlıdır ve tüm koşullar yerine getirilmediği sürece daha fazla yürütmeyi engeller.",
|
||||
"learn_more": "Koşullar hakkında daha fazla bilgi edinin",
|
||||
"name": "Şart",
|
||||
"type_select": "Koşul türü",
|
||||
@ -860,6 +888,7 @@
|
||||
},
|
||||
"edit_ui": "UI ile düzenle",
|
||||
"edit_yaml": "YAML olarak düzenle",
|
||||
"enable_disable": "Otomasyonu etkinleştirme / devre dışı bırakma",
|
||||
"introduction": "Evinizi canlandırmak için otomasyonları kullanın",
|
||||
"load_error_not_editable": "Yalnızca automations.yaml içindeki otomasyonlar düzenlenebilir.",
|
||||
"load_error_unknown": "Otomasyon yüklenirken hata oluştu ( {err_no} ).",
|
||||
@ -870,6 +899,7 @@
|
||||
"delete_confirm": "Silmek istediğinizden emin misiniz?",
|
||||
"duplicate": "Yedekle",
|
||||
"header": "Tetikleyiciler",
|
||||
"introduction": "Tetikleyiciler, bir otomasyon kuralının işlenmesini başlatan şeydir. Aynı kural için birden çok tetikleyici belirtmek mümkündür. Bir tetikleyici başladıktan sonra, Home Assistant varsa koşulları doğrular ve eylemi çağırır.",
|
||||
"learn_more": "Tetikleyiciler hakkında daha fazla bilgi edinin",
|
||||
"name": "Tetik",
|
||||
"type_select": "Tetikleyici tipi",
|
||||
@ -962,6 +992,7 @@
|
||||
"delete_confirm": "Bu otomasyonu silmek istediğinizden emin misin?",
|
||||
"edit_automation": "Otomasyonu düzenle",
|
||||
"header": "Otomasyon Düzenleyici",
|
||||
"introduction": "Otomasyon editörü, otomasyonlar oluşturmanıza ve düzenlemenize izin verir. Home Assistant'ı doğru yapılandırdığınızdan emin olmak için lütfen aşağıdaki bağlantıyı takip edin.",
|
||||
"learn_more": "Otomasyonlar hakkında daha fazla bilgi edinin",
|
||||
"no_automations": "Düzenlenebilir otomasyon bulamadık",
|
||||
"only_editable": "Yalnızca automations.yaml dosyasında tanımlanan otomasyonlar düzenlenebilir.",
|
||||
@ -1116,6 +1147,7 @@
|
||||
"elevation": "Yükseklik",
|
||||
"elevation_feet": "Ayak",
|
||||
"elevation_meters": "metre",
|
||||
"imperial_example": "Fahrenheit, pound",
|
||||
"latitude": "Enlem",
|
||||
"location_name": "Home Assistant kurulumunuzun adı",
|
||||
"longitude": "Boylam",
|
||||
@ -1224,7 +1256,9 @@
|
||||
},
|
||||
"entities": {
|
||||
"caption": "Varlıklar",
|
||||
"description": "Bilinen tüm varlıklara genel bakış.",
|
||||
"editor": {
|
||||
"confirm_delete": "Bu girişi silmek istediğinizden emin misiniz?",
|
||||
"default_name": "Alan Ekle ",
|
||||
"delete": "SİL",
|
||||
"enabled_cause": "{Neden} tarafından devre dışı bırakılmış.",
|
||||
@ -1233,6 +1267,7 @@
|
||||
"entity_id": "Varlık kimliği",
|
||||
"name": "Ad Geçersiz Kılma",
|
||||
"note": "Not: bu henüz tüm entegrasyonlarla çalışmayabilir.",
|
||||
"unavailable": "Bu varlık şu anda kullanılamıyor.",
|
||||
"update": "GÜNCELLEme"
|
||||
},
|
||||
"picker": {
|
||||
@ -1264,6 +1299,7 @@
|
||||
"confirm_title": "{number} varlığı kaldırmak istiyor musunuz?"
|
||||
},
|
||||
"selected": "{number} seçildi",
|
||||
"show_disabled": "Devre dışı bırakılan varlıkları göster",
|
||||
"status": {
|
||||
"disabled": "Devre dışı",
|
||||
"ok": "Tamam",
|
||||
@ -1416,6 +1452,7 @@
|
||||
},
|
||||
"server_control": {
|
||||
"caption": "Server Kontrolleri",
|
||||
"description": "Home Assistant sunucusunu yeniden başlatın veya durdurun",
|
||||
"section": {
|
||||
"reloading": {
|
||||
"automation": "Otomasyonları yeniden yükle",
|
||||
@ -1432,6 +1469,7 @@
|
||||
"confirm_restart": "Home Assistant'ı yeniden başlatmak istediğinizden emin misin?",
|
||||
"confirm_stop": "Home Assistant'ı durdurmak istediğinizden emin misin?",
|
||||
"heading": "Sunucu yönetimi",
|
||||
"introduction": "Home Assistant sunucunuzu kontrol edin.. Home Assistant üzerinden",
|
||||
"restart": "Yeniden başlat",
|
||||
"stop": "Durdur"
|
||||
},
|
||||
@ -1517,6 +1555,11 @@
|
||||
"group_binding": {
|
||||
"bind_button_help": "Seçilen grubu seçilen aygıt kümelerine bağlayın.",
|
||||
"bind_button_label": "Grupla",
|
||||
"cluster_selection_help": "Seçili gruba bağlaşacak kümeleri seçin.",
|
||||
"group_picker_help": "Bağlama komutu vermek için bir grup seçin.",
|
||||
"group_picker_label": "Bağlanabilir Gruplar",
|
||||
"header": "Grup Bağlama",
|
||||
"introduction": "Grupları bağlama ve çözme.",
|
||||
"unbind_button_label": "Grubu Çöz"
|
||||
},
|
||||
"groups": {
|
||||
@ -1528,6 +1571,7 @@
|
||||
"create_group_details": "Yeni bir zigbee grubu oluşturmak için gerekli ayrıntıları girin",
|
||||
"creating_group": "Grup Oluşturma",
|
||||
"description": "Zigbee grupları oluşturma ve değiştirme",
|
||||
"group_details": "İşte seçilen Zigbee grubu için tüm detaylar.",
|
||||
"group_id": "Grup kimliği",
|
||||
"group_info": "Grup Bilgisi",
|
||||
"group_name_placeholder": "Grup Adı",
|
||||
@ -1535,13 +1579,15 @@
|
||||
"group-header": "Zigbee Ev Otomasyonu - Grup Detayları",
|
||||
"groups": "Gruplar",
|
||||
"groups-header": "Zigbee Ev Otomasyonu - Grup Yönetimi",
|
||||
"header": "Zigbee Ev Otomasyonu - Grup Yönetimi",
|
||||
"introduction": "Zigbee grupları oluşturma ve değiştirme",
|
||||
"manage_groups": "Zigbee Gruplarını Yönetin",
|
||||
"members": "Üyeler",
|
||||
"remove_groups": "Grupları Kaldır",
|
||||
"remove_members": "Üyeleri Kaldır",
|
||||
"removing_groups": "Grupları Kaldırma",
|
||||
"removing_members": "Üyeleri Kaldırma"
|
||||
"removing_members": "Üyeleri Kaldırma",
|
||||
"zha_zigbee_groups": "ZHA Zigbee Grupları"
|
||||
},
|
||||
"header": "Zigbee Ev Otomasyonunu Yapılandırma",
|
||||
"introduction": "Burada ZHA bileşenini yapılandırmak mümkündür. Kullanıcı arayüzünden henüz her şey yapılandırılamıyor, ancak üzerinde çalışıyoruz.",
|
||||
@ -1552,13 +1598,19 @@
|
||||
"header": "Cihaz yönetimi",
|
||||
"hint_wakeup": "Xiaomi sensörleri gibi bazı cihazlarda, onlarla etkileşime girerken cihazları uyanık tutan ~ 5 saniyelik aralıklarla basabileceğiniz bir uyanma düğmesi bulunur."
|
||||
},
|
||||
"services": {
|
||||
"remove": "Bir cihazı ZigBee ağından kaldırın.",
|
||||
"updateDeviceName": "Aygıt kayıt defterinde bu aygıt için özel bir ad ayarlayın."
|
||||
},
|
||||
"title": "Zigbee Ev Otomasyonu"
|
||||
},
|
||||
"zone": {
|
||||
"add_zone": "Bölge Ekle",
|
||||
"caption": "bölgeler",
|
||||
"configured_in_yaml": "Configuration.yaml aracılığıyla yapılandırılan bölgeler kullanıcı arayüzü aracılığıyla düzenlenemez.",
|
||||
"confirm_delete": "Bu bölgeyi silmek istediğinizden emin misiniz?",
|
||||
"create_zone": "Bölge Oluştur",
|
||||
"description": "Kişileri izlemek istediğiniz bölgeleri yönetin.",
|
||||
"detail": {
|
||||
"create": "Oluştur",
|
||||
"delete": "Sil",
|
||||
@ -1573,7 +1625,8 @@
|
||||
"required_error_msg": "Bu alan gereklidir",
|
||||
"update": "Güncelle"
|
||||
},
|
||||
"edit_home_zone": "Evinizin konumu genel konfigürasyonda değiştirilebilir."
|
||||
"edit_home_zone": "Evinizin konumu genel konfigürasyonda değiştirilebilir.",
|
||||
"no_zones_created_yet": "Görünüşe göre henüz herhangi bir bölge oluşturmadınız."
|
||||
},
|
||||
"zwave": {
|
||||
"caption": "Z-Wave",
|
||||
@ -1585,22 +1638,38 @@
|
||||
},
|
||||
"description": "Z-Wave ağınızı yönetin",
|
||||
"learn_more": "Z-Wave hakkında daha fazla bilgi edinin",
|
||||
"network_management": {
|
||||
"header": "Z-Wave Ağ Yönetimi"
|
||||
},
|
||||
"network_status": {
|
||||
"network_started": "Z-Wave Ağı Başlatıldı",
|
||||
"network_started_note_all_queried": "Tüm düğümler sorgulandı.",
|
||||
"network_starting": "Z-Wave Ağı başlatılıyor ...",
|
||||
"network_stopped": "Z-Wave Ağı Durduruldu"
|
||||
},
|
||||
"node_config": {
|
||||
"config_parameter": "Yapılandırma Parametresi",
|
||||
"config_value": "Yapılandırma Değeri",
|
||||
"false": "Yanlış",
|
||||
"header": "Düğüm Yapılandırma Seçenekleri",
|
||||
"seconds": "Saniye",
|
||||
"set_config_parameter": "Yapılandırma parametresini belirle",
|
||||
"set_wakeup": "Uyandırma Aralığı Ayarla",
|
||||
"true": "Doğru"
|
||||
},
|
||||
"services": {
|
||||
"add_node": "Düğüm Ekle",
|
||||
"add_node_secure": "Güvenli Düğüm Ekle",
|
||||
"cancel_command": "Komutu İptal Et",
|
||||
"heal_network": "Ağı İyileştir",
|
||||
"remove_node": "Düğümü Kaldır",
|
||||
"save_config": "Config'i Kaydet",
|
||||
"start_network": "Ağı Başlat",
|
||||
"stop_network": "Ağı Durdur",
|
||||
"test_network": "Test Ağı"
|
||||
},
|
||||
"values": {
|
||||
"header": "Düğüm Değerleri"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1656,7 +1725,8 @@
|
||||
"multiple_messages": "ileti ilk önce {time} meydana geldi ve {counter} kez gösterildi",
|
||||
"no_errors": "Herhangi bir hata rapor edilmiştir.",
|
||||
"no_issues": "Yeni bir sorun yok!",
|
||||
"refresh": "Yenile"
|
||||
"refresh": "Yenile",
|
||||
"title": "Günlük"
|
||||
},
|
||||
"mqtt": {
|
||||
"description_listen": "Bir konuyu dinle",
|
||||
@ -1752,6 +1822,7 @@
|
||||
}
|
||||
},
|
||||
"changed_toast": {
|
||||
"message": "Lovelace UI yapılandırması güncellendi, değişiklikleri görmek için yenilensin mi?",
|
||||
"refresh": "Yenile"
|
||||
},
|
||||
"editor": {
|
||||
@ -1763,6 +1834,9 @@
|
||||
"available_states": "Mevcut Durumlar",
|
||||
"name": "Alarm Paneli"
|
||||
},
|
||||
"button": {
|
||||
"name": "Düğme"
|
||||
},
|
||||
"conditional": {
|
||||
"name": "Koşullu"
|
||||
},
|
||||
@ -1874,7 +1948,8 @@
|
||||
"toggle_editor": "Düzenleyiciye Geçiş"
|
||||
},
|
||||
"edit_lovelace": {
|
||||
"edit_title": "Başlığı düzenle"
|
||||
"edit_title": "Başlığı düzenle",
|
||||
"header": "Lovelace kullanıcı arayüzünüzün başlığı"
|
||||
},
|
||||
"edit_view": {
|
||||
"add": "Görünüm ekle",
|
||||
@ -1956,6 +2031,7 @@
|
||||
},
|
||||
"page-authorize": {
|
||||
"abort_intro": "Giriş iptal edildi",
|
||||
"authorizing_client": "{clientId}'ye Home Assistant erişim izni vermek üzeresiniz.",
|
||||
"form": {
|
||||
"providers": {
|
||||
"command_line": {
|
||||
@ -2172,6 +2248,7 @@
|
||||
"push_notifications": {
|
||||
"description": "Bu cihaza bildirimler gönder",
|
||||
"error_load_platform": "Notify.html5'i yapılandırın.",
|
||||
"error_use_https": "Önyüz için SSL'nin etkinleştirilmesini gerektirir.",
|
||||
"header": "Bildirimleri",
|
||||
"link_promo": "Daha fazla bilgi edinin",
|
||||
"push_notifications": "Bildirimleri"
|
||||
@ -2180,6 +2257,7 @@
|
||||
"confirm_delete": "{name} için yenileme anahtarını silmek istediğinizden emin misiniz?",
|
||||
"created_at": "{date} tarihinde oluşturuldu",
|
||||
"current_token_tooltip": "Geçerli yenileme anahtarı silinemedi",
|
||||
"delete_failed": "Yenileme anahtarı silinemedi.",
|
||||
"description": "Her yenileme jetonu bir oturum açma oturumunu temsil eder. Yenileme jetonları, çıkış yapmak istediğinizde otomatik olarak kaldırılacaktır. Aşağıdaki yenileme jetonları hesabınız için şu anda aktif.",
|
||||
"header": "Yenileme Anahtarları",
|
||||
"last_used": "En son {date} tarihinde {location} konumundan kullanıldı",
|
||||
|
@ -600,6 +600,10 @@
|
||||
},
|
||||
"updater": {
|
||||
"title": "Інструкції по оновленню"
|
||||
},
|
||||
"vacuum": {
|
||||
"start_pause": "Початок/Пауза",
|
||||
"stop": "Зупинити"
|
||||
}
|
||||
},
|
||||
"more_info_settings": {
|
||||
@ -1178,6 +1182,8 @@
|
||||
"details": "Тут ви знайдете всі деталі вашого пристрою.",
|
||||
"device_not_found": "Пристрій не знайдено",
|
||||
"info": "Інформація про пристрій",
|
||||
"scenes": "Сцени",
|
||||
"scripts": "Скрипти",
|
||||
"unknown_error": "Невідома помилка",
|
||||
"unnamed_device": "Пристрій без імені"
|
||||
},
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user