Compare commits

...

45 Commits

Author SHA1 Message Date
Bram Kragten
c10dca9c7b Merge pull request #7910 from home-assistant/dev 2020-12-04 21:46:54 +01:00
Bram Kragten
7f2ebb4bde Bumped version to 20201204.0 2020-12-04 21:33:37 +01:00
Bram Kragten
f1abb60e4a Add message when no matches for selectors, clear config when deleted (#7906) 2020-12-04 20:49:24 +01:00
Bram Kragten
e014c7aff6 Entity is not required for button card (#7909)
Fixes https://github.com/home-assistant/frontend/issues/7908
2020-12-04 12:02:58 -06:00
Bram Kragten
b79c03433e Don't update device picker while open (#7903) 2020-12-04 12:05:01 +01:00
HomeAssistant Azure
34eb4d974d [ci skip] Translation update 2020-12-04 00:32:26 +00:00
Zack Barett
3264be3c5e Move main function to events on hui-view for custom views to use (#7861) 2020-12-03 18:16:55 -06:00
Bram Kragten
655f4f75fb Change import blueprint fab icon (#7894) 2020-12-03 22:41:13 +01:00
Bram Kragten
4383f31696 Translation logic tweaks (#7901)
* Translation logic tweaks

* Comments
2020-12-03 22:29:52 +01:00
Paulus Schoutsen
99eb15d15e Improve blueprint translations (#7892) 2020-12-03 18:08:14 +01:00
Bram Kragten
2682c6e150 Merge pull request #7891 from home-assistant/dev 2020-12-03 17:22:08 +01:00
Bram Kragten
3a5d854e6d Bumped version to 20201203.0 2020-12-03 17:00:56 +01:00
Bram Kragten
1e90c6387c More BP tweaks (#7884) 2020-12-03 09:59:43 -06:00
Philip Allgaier
2cca25f4d0 Navigate back to area overview after area deletion (#7890) 2020-12-03 16:52:44 +01:00
Bram Kragten
565724d201 Fix translation race condition? (#7885) 2020-12-03 16:52:09 +01:00
Bram Kragten
3e4955becd UI tweaks for BP (#7883)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2020-12-03 14:18:17 +01:00
Philip Allgaier
7b560c727f Adjust text since entities can now be in areas too (#7880) 2020-12-03 14:05:16 +01:00
HomeAssistant Azure
35abd9dfdb [ci skip] Translation update 2020-12-03 00:32:38 +00:00
Bram Kragten
b7ccf3e0e5 Merge pull request #7875 from home-assistant/dev 2020-12-02 19:51:36 +01:00
Bram Kragten
0d9ab8fdd0 Bumped version to 20201202.0 2020-12-02 19:31:43 +01:00
Bram Kragten
303f9290a8 Add more device disabled ui (#7874) 2020-12-02 19:31:06 +01:00
Bram Kragten
e0c4dc08a1 Tooltip tweak target picker (#7870) 2020-12-02 11:21:51 -06:00
Bram Kragten
8c655883fe Add device disabled reason (#7873) 2020-12-02 18:20:29 +01:00
Bram Kragten
ba90785115 Fix card picker cards (#7871) 2020-12-02 17:46:30 +01:00
Bram Kragten
7b392b626b Hardcode history card stub entity to sun.sun (#7760) 2020-12-02 10:16:46 -06:00
Zack Barett
8e4ceb7d48 Fix View Background Colors (#7823) 2020-12-02 17:08:18 +01:00
Philip Allgaier
2ab1c6e9a9 Make media player card work as square + add to gallery + icon pos tweaks (#7727) 2020-12-02 16:57:19 +01:00
Adam Ernst
dbdced0971 Improve descriptions for Configuration entries (#7606) 2020-12-02 16:36:21 +01:00
Philip Allgaier
5e481880bd Allow empty entities array with entity-filter (#7854) 2020-12-02 16:34:59 +01:00
Kendell R
faec063f34 Add --masonry-view-card-margin (#7395) 2020-12-02 16:22:20 +01:00
Zack Barett
bbea38d227 Lovelace Card Editor: Preview Background (#7678) 2020-12-02 16:19:01 +01:00
Kendell R
a0ef60de49 Make card picker border follow standards (#7162) 2020-12-02 16:14:46 +01:00
Philip Allgaier
3313572606 Improve password change card (#7756)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2020-12-02 16:00:49 +01:00
Philip Allgaier
c4f850cb14 Cleanup created user if person creation is cancelled (#7865) 2020-12-02 15:45:24 +01:00
Erik Montnemery
3bdab738c6 Support disabling devices (#7715)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
2020-12-02 15:40:35 +01:00
Philip Allgaier
faaef31b9f Show proper error message if username already used (#7866) 2020-12-02 15:35:38 +01:00
Philip Allgaier
ca7b8b8b4c Add option to deactivate a user (#7757) 2020-12-02 15:33:11 +01:00
Philip Allgaier
9ca84e0694 Ensure "false" is set as default for "continue_on_timeout" (#7862) 2020-12-02 15:22:17 +01:00
Philip Allgaier
daaf2b1796 Ensure push notification description reacts to language change (#7856) 2020-12-02 12:11:47 +01:00
Bram Kragten
25f7cbea5a Add target selector (#7864)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
2020-12-02 12:10:31 +01:00
Josh McCarty
c485ea9d7b Add number formatting to counter entity state display (#7868) 2020-12-02 11:51:56 +01:00
HomeAssistant Azure
295390c8e9 [ci skip] Translation update 2020-12-02 00:32:30 +00:00
Bram Kragten
3ebf816ce2 Fix height of ha-icon-input (#7767) 2020-12-01 22:51:15 +01:00
HomeAssistant Azure
0e362b851b [ci skip] Translation update 2020-12-01 00:32:47 +00:00
Bram Kragten
50e7410002 Merge pull request #7833 from home-assistant/dev 2020-11-27 00:16:56 +01:00
87 changed files with 3712 additions and 940 deletions

View File

@@ -7,8 +7,8 @@ export const createMediaPlayerEntities = () => [
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
media_artist: "Technohead",
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
supported_features: 195135,
// Select Source + Stop + Clear + Play + Shuffle Set
supported_features: 64063,
entity_picture: "/images/album_cover_2.jpg",
media_duration: 300,
media_position: 50,
@@ -24,8 +24,8 @@ export const createMediaPlayerEntities = () => [
media_title: "I Wanna Be A Hippy (Flamman & Abraxas Radio Mix)",
media_artist: "Technohead",
// Pause + Seek + Volume Set + Volume Mute + Previous Track + Next Track + Play Media +
// Select Source + Stop + Clear + Play + Shuffle Set
supported_features: 64063,
// Select Source + Stop + Clear + Play + Shuffle Set + Browse Media
supported_features: 195135,
entity_picture: "/images/album_cover.jpg",
media_duration: 300,
media_position: 0,

View File

@@ -146,6 +146,16 @@ const CONFIGS = [
entity: media_player.receiver_off
`,
},
{
heading: "Grid Full Size",
config: `
- type: grid
columns: 1
cards:
- type: media-control
entity: media_player.music_paused
`,
},
];
class DemoHuiMediControlCard extends PolymerElement {

View File

@@ -74,9 +74,7 @@ export class HassioUpdate extends LitElement {
"Supervisor",
this.supervisor.supervisor,
"hassio/supervisor/update",
`https://github.com//home-assistant/hassio/releases/tag/${
this.supervisor.supervisor.version_latest
}`
`https://github.com//home-assistant/hassio/releases/tag/${this.supervisor.supervisor.version_latest}`
)}
${this.supervisor.host.features.includes("hassos")
? this._renderUpdateCard(

View File

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

View File

@@ -0,0 +1,6 @@
export const ensureArray = (value?: any) => {
if (!value || Array.isArray(value)) {
return value;
}
return [value];
};

View File

@@ -67,6 +67,10 @@ export const computeStateDisplay = (
}
}
if (domain === "counter") {
return formatNumber(compareState, language);
}
return (
// Return device class translation
(stateObj.attributes.device_class &&

View File

@@ -139,7 +139,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
private _filteredDevices: DeviceRegistryEntry[] = [];
private _getDevices = memoizeOne(
private _getAreasWithDevices = memoizeOne(
(
devices: DeviceRegistryEntry[],
areas: AreaRegistryEntry[],
@@ -277,7 +277,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) {
if (!this._devices || !this._areas || !this._entities) {
return html``;
}
const areas = this._getDevices(
const areas = this._getAreasWithDevices(
this._devices,
this._areas,
this._entities,

View File

@@ -1,4 +1,5 @@
import "../ha-icon-button";
import "../ha-svg-icon";
import "@material/mwc-icon-button/mwc-icon-button";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
@@ -12,6 +13,8 @@ import {
html,
LitElement,
property,
PropertyValues,
query,
TemplateResult,
} from "lit-element";
import memoizeOne from "memoize-one";
@@ -35,6 +38,7 @@ import {
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
import { PolymerChangedEvent } from "../../polymer-types";
import { HomeAssistant } from "../../types";
import { mdiClose, mdiMenuUp, mdiMenuDown } from "@mdi/js";
interface Device {
name: string;
@@ -111,6 +115,10 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
@property({ type: Boolean })
private _opened?: boolean;
@query("vaadin-combo-box-light", true) private _comboBox!: HTMLElement;
private _init = false;
private _getDevices = memoizeOne(
(
devices: DeviceRegistryEntry[],
@@ -122,18 +130,27 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
deviceFilter: this["deviceFilter"]
): Device[] => {
if (!devices.length) {
return [];
return [
{
id: "",
area: "",
name: this.hass.localize("ui.components.device-picker.no_devices"),
},
];
}
const deviceEntityLookup: DeviceEntityLookup = {};
for (const entity of entities) {
if (!entity.device_id) {
continue;
if (includeDomains || excludeDomains || includeDeviceClasses) {
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);
}
if (!(entity.device_id in deviceEntityLookup)) {
deviceEntityLookup[entity.device_id] = [];
}
deviceEntityLookup[entity.device_id].push(entity);
}
const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
@@ -141,7 +158,9 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
areaLookup[area.area_id] = area;
}
let inputDevices = [...devices];
let inputDevices = devices.filter(
(device) => device.id === this.value || !device.disabled_by
);
if (includeDomains) {
inputDevices = inputDevices.filter((device) => {
@@ -208,6 +227,15 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
: this.hass.localize("ui.components.device-picker.no_area"),
};
});
if (!outputDevices.length) {
return [
{
id: "",
area: "",
name: this.hass.localize("ui.components.device-picker.no_match"),
},
];
}
if (outputDevices.length === 1) {
return outputDevices;
}
@@ -215,6 +243,18 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
}
);
public open() {
this.updateComplete.then(() => {
(this.shadowRoot?.querySelector("vaadin-combo-box-light") as any)?.open();
});
}
public focus() {
this.updateComplete.then(() => {
this.shadowRoot?.querySelector("paper-input")?.focus();
});
}
public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
@@ -229,25 +269,33 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
];
}
protected updated(changedProps: PropertyValues) {
if (
(!this._init && this.devices && this.areas && this.entities) ||
(changedProps.has("_opened") && this._opened)
) {
this._init = true;
(this._comboBox as any).items = this._getDevices(
this.devices!,
this.areas!,
this.entities!,
this.includeDomains,
this.excludeDomains,
this.includeDeviceClasses,
this.deviceFilter
);
}
}
protected render(): TemplateResult {
if (!this.devices || !this.areas || !this.entities) {
return html``;
}
const devices = this._getDevices(
this.devices,
this.areas,
this.entities,
this.includeDomains,
this.excludeDomains,
this.includeDeviceClasses,
this.deviceFilter
);
return html`
<vaadin-combo-box-light
item-value-path="id"
item-id-path="id"
item-label-path="name"
.items=${devices}
.value=${this._value}
.renderer=${rowRenderer}
@opened-changed=${this._openedChanged}
@@ -265,34 +313,30 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
>
${this.value
? html`
<ha-icon-button
aria-label=${this.hass.localize(
<mwc-icon-button
.label=${this.hass.localize(
"ui.components.device-picker.clear"
)}
slot="suffix"
class="clear-button"
icon="hass:close"
@click=${this._clearValue}
no-ripple
>
Clear
</ha-icon-button>
`
: ""}
${devices.length > 0
? html`
<ha-icon-button
aria-label=${this.hass.localize(
"ui.components.device-picker.show_devices"
)}
slot="suffix"
class="toggle-button"
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
>
Toggle
</ha-icon-button>
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
</mwc-icon-button>
`
: ""}
<mwc-icon-button
.label=${this.hass.localize(
"ui.components.device-picker.show_devices"
)}
slot="suffix"
class="toggle-button"
>
<ha-svg-icon
.path=${this._opened ? mdiMenuUp : mdiMenuDown}
></ha-svg-icon>
</mwc-icon-button>
</paper-input>
</vaadin-combo-box-light>
`;
@@ -329,7 +373,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) {
static get styles(): CSSResult {
return css`
paper-input > ha-icon-button {
paper-input > mwc-icon-button {
--mdc-icon-button-size: 24px;
padding: 2px;
color: var(--secondary-text-color);

View File

@@ -101,6 +101,18 @@ export class HaEntityPicker extends LitElement {
@query("vaadin-combo-box-light", true) private _comboBox!: HTMLElement;
public open() {
this.updateComplete.then(() => {
(this.shadowRoot?.querySelector("vaadin-combo-box-light") as any)?.open();
});
}
public focus() {
this.updateComplete.then(() => {
this.shadowRoot?.querySelector("paper-input")?.focus();
});
}
private _initedStates = false;
private _states: HassEntity[] = [];
@@ -153,6 +165,24 @@ export class HaEntityPicker extends LitElement {
);
}
if (!states.length) {
return [
{
entity_id: "",
state: "",
last_changed: "",
last_updated: "",
context: { id: "", user_id: null },
attributes: {
friendly_name: this.hass!.localize(
"ui.components.entity.entity-picker.no_match"
),
icon: "mdi:magnify",
},
},
];
}
return states;
}
);
@@ -203,7 +233,6 @@ export class HaEntityPicker extends LitElement {
.label=${this.label === undefined
? this.hass.localize("ui.components.entity.entity-picker.entity")
: this.label}
.value=${this._value}
.disabled=${this.disabled}
class="input"
autocapitalize="none"

View File

@@ -1,4 +1,5 @@
import "./ha-icon-button";
import "./ha-svg-icon";
import "@material/mwc-icon-button/mwc-icon-button";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-item/paper-item-body";
@@ -14,6 +15,8 @@ import {
property,
internalProperty,
TemplateResult,
PropertyValues,
query,
} from "lit-element";
import { fireEvent } from "../common/dom/fire_event";
import {
@@ -29,6 +32,18 @@ import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { PolymerChangedEvent } from "../polymer-types";
import { HomeAssistant } from "../types";
import memoizeOne from "memoize-one";
import {
DeviceEntityLookup,
DeviceRegistryEntry,
subscribeDeviceRegistry,
} from "../data/device_registry";
import {
EntityRegistryEntry,
subscribeEntityRegistry,
} from "../data/entity_registry";
import { computeDomain } from "../common/entity/compute_domain";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import { mdiClose, mdiMenuDown, mdiMenuUp } from "@mdi/js";
const rowRenderer = (
root: HTMLElement,
@@ -71,31 +86,250 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
@property() public placeholder?: string;
@property() public _areas?: AreaRegistryEntry[];
@property({ type: Boolean, attribute: "no-add" })
public noAdd?: boolean;
/**
* Show only areas with entities from specific domains.
* @type {Array}
* @attr include-domains
*/
@property({ type: Array, attribute: "include-domains" })
public includeDomains?: string[];
/**
* Show no areas with entities of these domains.
* @type {Array}
* @attr exclude-domains
*/
@property({ type: Array, attribute: "exclude-domains" })
public excludeDomains?: string[];
/**
* Show only areas with entities of these device classes.
* @type {Array}
* @attr include-device-classes
*/
@property({ type: Array, attribute: "include-device-classes" })
public includeDeviceClasses?: string[];
@property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
@property() public entityFilter?: (entity: EntityRegistryEntry) => boolean;
@internalProperty() private _areas?: AreaRegistryEntry[];
@internalProperty() private _devices?: DeviceRegistryEntry[];
@internalProperty() private _entities?: EntityRegistryEntry[];
@internalProperty() private _opened?: boolean;
@query("vaadin-combo-box-light", true) private _comboBox!: HTMLElement;
private _init = false;
public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeAreaRegistry(this.hass.connection!, (areas) => {
this._areas = this.noAdd
? areas
: [
...areas,
{
area_id: "add_new",
name: this.hass.localize("ui.components.area-picker.add_new"),
},
];
this._areas = areas;
}),
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
this._devices = devices;
}),
subscribeEntityRegistry(this.hass.connection!, (entities) => {
this._entities = entities;
}),
];
}
public open() {
this.updateComplete.then(() => {
(this.shadowRoot?.querySelector("vaadin-combo-box-light") as any)?.open();
});
}
public focus() {
this.updateComplete.then(() => {
this.shadowRoot?.querySelector("paper-input")?.focus();
});
}
private _getAreas = memoizeOne(
(
areas: AreaRegistryEntry[],
devices: DeviceRegistryEntry[],
entities: EntityRegistryEntry[],
includeDomains: this["includeDomains"],
excludeDomains: this["excludeDomains"],
includeDeviceClasses: this["includeDeviceClasses"],
deviceFilter: this["deviceFilter"],
entityFilter: this["entityFilter"],
noAdd: this["noAdd"]
): AreaRegistryEntry[] => {
if (!areas.length) {
return [
{
area_id: "",
name: this.hass.localize("ui.components.area-picker.no_areas"),
},
];
}
const deviceEntityLookup: DeviceEntityLookup = {};
let inputDevices: DeviceRegistryEntry[] | undefined;
let inputEntities: EntityRegistryEntry[] | undefined;
if (includeDomains || excludeDomains || includeDeviceClasses) {
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);
}
inputDevices = devices;
inputEntities = entities.filter((entity) => entity.area_id);
} else if (deviceFilter) {
inputDevices = devices;
} else if (entityFilter) {
inputEntities = entities.filter((entity) => entity.area_id);
}
if (includeDomains) {
inputDevices = inputDevices!.filter((device) => {
const devEntities = deviceEntityLookup[device.id];
if (!devEntities || !devEntities.length) {
return false;
}
return deviceEntityLookup[device.id].some((entity) =>
includeDomains.includes(computeDomain(entity.entity_id))
);
});
inputEntities = inputEntities!.filter((entity) =>
includeDomains.includes(computeDomain(entity.entity_id))
);
}
if (excludeDomains) {
inputDevices = inputDevices!.filter((device) => {
const devEntities = deviceEntityLookup[device.id];
if (!devEntities || !devEntities.length) {
return true;
}
return entities.every(
(entity) =>
!excludeDomains.includes(computeDomain(entity.entity_id))
);
});
inputEntities = inputEntities!.filter(
(entity) => !excludeDomains.includes(computeDomain(entity.entity_id))
);
}
if (includeDeviceClasses) {
inputDevices = inputDevices!.filter((device) => {
const devEntities = deviceEntityLookup[device.id];
if (!devEntities || !devEntities.length) {
return false;
}
return deviceEntityLookup[device.id].some((entity) => {
const stateObj = this.hass.states[entity.entity_id];
if (!stateObj) {
return false;
}
return (
stateObj.attributes.device_class &&
includeDeviceClasses.includes(stateObj.attributes.device_class)
);
});
});
inputEntities = inputEntities!.filter((entity) => {
const stateObj = this.hass.states[entity.entity_id];
return (
stateObj.attributes.device_class &&
includeDeviceClasses.includes(stateObj.attributes.device_class)
);
});
}
if (deviceFilter) {
inputDevices = inputDevices!.filter((device) => deviceFilter!(device));
}
if (entityFilter) {
inputEntities = inputEntities!.filter((entity) =>
entityFilter!(entity)
);
}
let outputAreas = areas;
let areaIds: string[] | undefined;
if (inputDevices) {
areaIds = inputDevices
.filter((device) => device.area_id)
.map((device) => device.area_id!);
}
if (inputEntities) {
areaIds = (areaIds ?? []).concat(
inputEntities
.filter((entity) => entity.area_id)
.map((entity) => entity.area_id!)
);
}
if (areaIds) {
outputAreas = areas.filter((area) => areaIds!.includes(area.area_id));
}
if (!outputAreas.length) {
outputAreas = [
{
area_id: "",
name: this.hass.localize("ui.components.area-picker.no_match"),
},
];
}
return noAdd
? outputAreas
: [
...outputAreas,
{
area_id: "add_new",
name: this.hass.localize("ui.components.area-picker.add_new"),
},
];
}
);
protected updated(changedProps: PropertyValues) {
if (
(!this._init && this._devices && this._areas && this._entities) ||
(changedProps.has("_opened") && this._opened)
) {
this._init = true;
(this._comboBox as any).items = this._getAreas(
this._areas!,
this._devices!,
this._entities!,
this.includeDomains,
this.excludeDomains,
this.includeDeviceClasses,
this.deviceFilter,
this.entityFilter,
this.noAdd
);
}
}
protected render(): TemplateResult {
if (!this._areas) {
if (!this._devices || !this._areas || !this._entities) {
return html``;
}
return html`
@@ -103,7 +337,6 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
item-value-path="area_id"
item-id-path="area_id"
item-label-path="name"
.items=${this._areas}
.value=${this._value}
.renderer=${rowRenderer}
@opened-changed=${this._openedChanged}
@@ -124,34 +357,28 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
>
${this.value
? html`
<ha-icon-button
aria-label=${this.hass.localize(
<mwc-icon-button
.label=${this.hass.localize(
"ui.components.area-picker.clear"
)}
slot="suffix"
class="clear-button"
icon="hass:close"
@click=${this._clearValue}
no-ripple
>
${this.hass.localize("ui.components.area-picker.clear")}
</ha-icon-button>
`
: ""}
${this._areas.length > 0
? html`
<ha-icon-button
aria-label=${this.hass.localize(
"ui.components.area-picker.show_areas"
)}
slot="suffix"
class="toggle-button"
.icon=${this._opened ? "hass:menu-up" : "hass:menu-down"}
>
${this.hass.localize("ui.components.area-picker.toggle")}
</ha-icon-button>
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
</mwc-icon-button>
`
: ""}
<mwc-icon-button
.label=${this.hass.localize("ui.components.area-picker.toggle")}
slot="suffix"
class="toggle-button"
>
<ha-svg-icon
.path=${this._opened ? mdiMenuUp : mdiMenuDown}
></ha-svg-icon>
</mwc-icon-button>
</paper-input>
</vaadin-combo-box-light>
`;
@@ -227,7 +454,7 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) {
static get styles(): CSSResult {
return css`
paper-input > ha-icon-button {
paper-input > mwc-icon-button {
--mdc-icon-button-size: 24px;
padding: 2px;
color: var(--secondary-text-color);

View File

@@ -52,6 +52,7 @@ class HaBluePrintPicker extends LitElement {
.label=${this.label ||
this.hass.localize("ui.components.blueprint-picker.label")}
.disabled=${this.disabled}
horizontal-align="left"
>
<paper-listbox
slot="dropdown-content"
@@ -110,6 +111,9 @@ class HaBluePrintPicker extends LitElement {
paper-listbox {
min-width: 200px;
}
paper-item {
cursor: pointer;
}
`;
}
}

View File

@@ -11,6 +11,7 @@ import {
import { fireEvent } from "../common/dom/fire_event";
import type { ToggleButton } from "../types";
import "./ha-svg-icon";
import "@material/mwc-button/mwc-button";
@customElement("ha-button-toggle-group")
export class HaButtonToggleGroup extends LitElement {
@@ -21,17 +22,22 @@ export class HaButtonToggleGroup extends LitElement {
protected render(): TemplateResult {
return html`
<div>
${this.buttons.map(
(button) => html`
<mwc-icon-button
.label=${button.label}
.value=${button.value}
?active=${this.active === button.value}
@click=${this._handleClick}
>
<ha-svg-icon .path=${button.iconPath}></ha-svg-icon>
</mwc-icon-button>
`
${this.buttons.map((button) =>
button.iconPath
? html`<mwc-icon-button
.label=${button.label}
.value=${button.value}
?active=${this.active === button.value}
@click=${this._handleClick}
>
<ha-svg-icon .path=${button.iconPath}></ha-svg-icon>
</mwc-icon-button>`
: html`<mwc-button
.value=${button.value}
?active=${this.active === button.value}
@click=${this._handleClick}
>${button.label}</mwc-button
>`
)}
</div>
`;
@@ -49,13 +55,15 @@ export class HaButtonToggleGroup extends LitElement {
--mdc-icon-button-size: var(--button-toggle-size, 36px);
--mdc-icon-size: var(--button-toggle-icon-size, 20px);
}
mwc-icon-button {
mwc-icon-button,
mwc-button {
border: 1px solid var(--primary-color);
border-right-width: 0px;
position: relative;
cursor: pointer;
}
mwc-icon-button::before {
mwc-icon-button::before,
mwc-button::before {
top: 0;
left: 0;
width: 100%;
@@ -67,17 +75,21 @@ export class HaButtonToggleGroup extends LitElement {
content: "";
transition: opacity 15ms linear, background-color 15ms linear;
}
mwc-icon-button[active]::before {
mwc-icon-button[active]::before,
mwc-button[active]::before {
opacity: var(--mdc-icon-button-ripple-opacity, 0.12);
}
mwc-icon-button:first-child {
mwc-icon-button:first-child,
mwc-button:first-child {
border-radius: 4px 0 0 4px;
}
mwc-icon-button:last-child {
mwc-icon-button:last-child,
mwc-button:last-child {
border-radius: 0 4px 4px 0;
border-right-width: 1px;
}
mwc-icon-button:only-child {
mwc-icon-button:only-child,
mwc-button:only-child {
border-radius: 4px;
border-right-width: 1px;
}

View File

@@ -60,8 +60,9 @@ export class HaIconInput extends LitElement {
static get styles() {
return css`
ha-icon {
position: relative;
bottom: 4px;
position: absolute;
bottom: 2px;
right: 0;
}
`;
}

View File

@@ -0,0 +1,45 @@
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
} from "lit-element";
import { HomeAssistant } from "../../types";
import { ActionSelector } from "../../data/selector";
import { Action } from "../../data/script";
import "../../panels/config/automation/action/ha-automation-action";
@customElement("ha-selector-action")
export class HaActionSelector extends LitElement {
@property() public hass!: HomeAssistant;
@property() public selector!: ActionSelector;
@property() public value?: Action;
@property() public label?: string;
protected render() {
return html`<ha-automation-action
.actions=${this.value || []}
.hass=${this.hass}
></ha-automation-action>`;
}
static get styles(): CSSResult {
return css`
ha-automation-action {
display: block;
margin-bottom: 16px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-selector-action": HaActionSelector;
}
}

View File

@@ -1,7 +1,16 @@
import { customElement, html, LitElement, property } from "lit-element";
import {
customElement,
html,
internalProperty,
LitElement,
property,
} from "lit-element";
import { HomeAssistant } from "../../types";
import { AreaSelector } from "../../data/selector";
import "../ha-area-picker";
import { ConfigEntry, getConfigEntries } from "../../data/config_entries";
import { DeviceRegistryEntry } from "../../data/device_registry";
import { EntityRegistryEntry } from "../../data/entity_registry";
@customElement("ha-selector-area")
export class HaAreaSelector extends LitElement {
@@ -13,14 +22,77 @@ export class HaAreaSelector extends LitElement {
@property() public label?: string;
@internalProperty() public _configEntries?: ConfigEntry[];
protected updated(changedProperties) {
if (changedProperties.has("selector")) {
const oldSelector = changedProperties.get("selector");
if (
oldSelector !== this.selector &&
this.selector.area.device?.integration
) {
this._loadConfigEntries();
}
}
}
protected render() {
return html`<ha-area-picker
.hass=${this.hass}
.value=${this.value}
.label=${this.label}
no-add
.deviceFilter=${(device) => this._filterDevices(device)}
.entityFilter=${(entity) => this._filterEntities(entity)}
.includeDeviceClasses=${this.selector.area.entity?.device_class
? [this.selector.area.entity.device_class]
: undefined}
.includeDomains=${this.selector.area.entity?.domain
? [this.selector.area.entity.domain]
: undefined}
></ha-area-picker>`;
}
private _filterEntities(entity: EntityRegistryEntry): boolean {
if (this.selector.area.entity?.integration) {
if (entity.platform !== this.selector.area.entity.integration) {
return false;
}
}
return true;
}
private _filterDevices(device: DeviceRegistryEntry): boolean {
if (
this.selector.area.device?.manufacturer &&
device.manufacturer !== this.selector.area.device.manufacturer
) {
return false;
}
if (
this.selector.area.device?.model &&
device.model !== this.selector.area.device.model
) {
return false;
}
if (this.selector.area.device?.integration) {
if (
this._configEntries &&
!this._configEntries.some((entry) =>
device.config_entries.includes(entry.entry_id)
)
) {
return false;
}
}
return true;
}
private async _loadConfigEntries() {
this._configEntries = (await getConfigEntries(this.hass)).filter(
(entry) => entry.domain === this.selector.area.device?.integration
);
}
}
declare global {

View File

@@ -63,7 +63,8 @@ export class HaDeviceSelector extends LitElement {
}
if (this.selector.device.integration) {
if (
!this._configEntries?.some((entry) =>
this._configEntries &&
!this._configEntries.some((entry) =>
device.config_entries.includes(entry.entry_id)
)
) {

View File

@@ -19,7 +19,7 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
@property() public selector!: EntitySelector;
@internalProperty() private _entities?: Record<string, string>;
@internalProperty() private _entityPlaformLookup?: Record<string, string>;
@property() public value?: any;
@@ -45,7 +45,7 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
}
entityLookup[confEnt.entity_id] = confEnt.platform;
}
this._entities = entityLookup;
this._entityPlaformLookup = entityLookup;
}),
];
}
@@ -66,8 +66,9 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
}
if (this.selector.entity.integration) {
if (
!this._entities ||
this._entities[entity.entity_id] !== this.selector.entity.integration
!this._entityPlaformLookup ||
this._entityPlaformLookup[entity.entity_id] !==
this.selector.entity.integration
) {
return false;
}

View File

@@ -0,0 +1,153 @@
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
} from "lit-element";
import { HomeAssistant } from "../../types";
import { TargetSelector } from "../../data/selector";
import { ConfigEntry, getConfigEntries } from "../../data/config_entries";
import { DeviceRegistryEntry } from "../../data/device_registry";
import "../ha-target-picker";
import "@material/mwc-list/mwc-list-item";
import "@polymer/paper-input/paper-input";
import "@material/mwc-list/mwc-list";
import {
EntityRegistryEntry,
subscribeEntityRegistry,
} from "../../data/entity_registry";
import { Target } from "../../data/target";
import "@material/mwc-tab-bar/mwc-tab-bar";
import "@material/mwc-tab/mwc-tab";
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
import { SubscribeMixin } from "../../mixins/subscribe-mixin";
@customElement("ha-selector-target")
export class HaTargetSelector extends SubscribeMixin(LitElement) {
@property() public hass!: HomeAssistant;
@property() public selector!: TargetSelector;
@property() public value?: Target;
@property() public label?: string;
@internalProperty() private _entityPlaformLookup?: Record<string, string>;
@internalProperty() private _configEntries?: ConfigEntry[];
public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeEntityRegistry(this.hass.connection!, (entities) => {
const entityLookup = {};
for (const confEnt of entities) {
if (!confEnt.platform) {
continue;
}
entityLookup[confEnt.entity_id] = confEnt.platform;
}
this._entityPlaformLookup = entityLookup;
}),
];
}
protected updated(changedProperties) {
if (changedProperties.has("selector")) {
const oldSelector = changedProperties.get("selector");
if (
oldSelector !== this.selector &&
this.selector.target.device?.integration
) {
this._loadConfigEntries();
}
}
}
protected render() {
return html`<ha-target-picker
.hass=${this.hass}
.value=${this.value}
.deviceFilter=${(device) => this._filterDevices(device)}
.entityRegFilter=${(entity: EntityRegistryEntry) =>
this._filterRegEntities(entity)}
.entityFilter=${(entity: HassEntity) => this._filterEntities(entity)}
.includeDeviceClasses=${this.selector.target.entity?.device_class
? [this.selector.target.entity.device_class]
: undefined}
.includeDomains=${this.selector.target.entity?.domain
? [this.selector.target.entity.domain]
: undefined}
></ha-target-picker>`;
}
private _filterEntities(entity: HassEntity): boolean {
if (this.selector.target.entity?.integration) {
if (
!this._entityPlaformLookup ||
this._entityPlaformLookup[entity.entity_id] !==
this.selector.target.entity.integration
) {
return false;
}
}
return true;
}
private _filterRegEntities(entity: EntityRegistryEntry): boolean {
if (this.selector.target.entity?.integration) {
if (entity.platform !== this.selector.target.entity.integration) {
return false;
}
}
return true;
}
private _filterDevices(device: DeviceRegistryEntry): boolean {
if (
this.selector.target.device?.manufacturer &&
device.manufacturer !== this.selector.target.device.manufacturer
) {
return false;
}
if (
this.selector.target.device?.model &&
device.model !== this.selector.target.device.model
) {
return false;
}
if (this.selector.target.device?.integration) {
if (
!this._configEntries?.some((entry) =>
device.config_entries.includes(entry.entry_id)
)
) {
return false;
}
}
return true;
}
private async _loadConfigEntries() {
this._configEntries = (await getConfigEntries(this.hass)).filter(
(entry) => entry.domain === this.selector.target.device?.integration
);
}
static get styles(): CSSResult {
return css`
ha-target-picker {
margin: 0 -8px;
display: block;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-selector-target": HaTargetSelector;
}
}

View File

@@ -5,9 +5,11 @@ import { HomeAssistant } from "../../types";
import "./ha-selector-entity";
import "./ha-selector-device";
import "./ha-selector-area";
import "./ha-selector-target";
import "./ha-selector-number";
import "./ha-selector-boolean";
import "./ha-selector-time";
import "./ha-selector-action";
import { Selector } from "../../data/selector";
@customElement("ha-selector")

View File

@@ -18,11 +18,6 @@ export class HaSettingsRow extends LitElement {
protected render(): SVGTemplateResult {
return html`
<style>
paper-item-body {
padding-right: 16px;
}
</style>
<paper-item-body
?two-line=${!this.threeLine}
?three-line=${this.threeLine}
@@ -43,6 +38,14 @@ export class HaSettingsRow extends LitElement {
align-self: auto;
align-items: center;
}
paper-item-body {
padding: 8px 16px 8px 0;
}
paper-item-body[two-line] {
min-height: calc(
var(--paper-item-body-two-line-min-height, 72px) - 16px
);
}
:host([narrow]) {
align-items: normal;
flex-direction: column;
@@ -52,6 +55,9 @@ export class HaSettingsRow extends LitElement {
::slotted(ha-switch) {
padding: 16px 0;
}
div[secondary] {
white-space: normal;
}
`;
}
}

View File

@@ -0,0 +1,604 @@
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
query,
unsafeCSS,
} from "lit-element";
import { HomeAssistant } from "../types";
// @ts-ignore
import chipStyles from "@material/chips/dist/mdc.chips.min.css";
import {
mdiSofa,
mdiDevices,
mdiClose,
mdiPlus,
mdiUnfoldMoreVertical,
} from "@mdi/js";
import "./ha-svg-icon";
import "./ha-icon";
import "@material/mwc-icon-button/mwc-icon-button";
import { classMap } from "lit-html/directives/class-map";
import "@material/mwc-button/mwc-button";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import {
AreaRegistryEntry,
subscribeAreaRegistry,
} from "../data/area_registry";
import {
DeviceRegistryEntry,
subscribeDeviceRegistry,
} from "../data/device_registry";
import {
EntityRegistryEntry,
subscribeEntityRegistry,
} from "../data/entity_registry";
import { SubscribeMixin } from "../mixins/subscribe-mixin";
import { computeStateName } from "../common/entity/compute_state_name";
import { stateIcon } from "../common/entity/state_icon";
import { fireEvent } from "../common/dom/fire_event";
import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import { computeDomain } from "../common/entity/compute_domain";
import { Target } from "../data/target";
import { ensureArray } from "../common/ensure-array";
import "./entity/ha-entity-picker";
import "./device/ha-device-picker";
import "./ha-area-picker";
import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
import "@polymer/paper-tooltip/paper-tooltip";
@customElement("ha-target-picker")
export class HaTargetPicker extends SubscribeMixin(LitElement) {
@property() public hass!: HomeAssistant;
@property() public value?: Target;
@property() public label?: string;
/**
* Show only targets with entities from specific domains.
* @type {Array}
* @attr include-domains
*/
@property({ type: Array, attribute: "include-domains" })
public includeDomains?: string[];
/**
* Show only targets with entities of these device classes.
* @type {Array}
* @attr include-device-classes
*/
@property({ type: Array, attribute: "include-device-classes" })
public includeDeviceClasses?: string[];
@property() public deviceFilter?: HaDevicePickerDeviceFilterFunc;
@property() public entityRegFilter?: (entity: EntityRegistryEntry) => boolean;
@property() public entityFilter?: HaEntityPickerEntityFilterFunc;
@internalProperty() private _areas?: { [areaId: string]: AreaRegistryEntry };
@internalProperty() private _devices?: {
[deviceId: string]: DeviceRegistryEntry;
};
@internalProperty() private _entities?: EntityRegistryEntry[];
@internalProperty() private _addMode?: "area_id" | "entity_id" | "device_id";
@query("#input") private _inputElement?;
public hassSubscribe(): UnsubscribeFunc[] {
return [
subscribeAreaRegistry(this.hass.connection!, (areas) => {
const areaLookup: { [areaId: string]: AreaRegistryEntry } = {};
for (const area of areas) {
areaLookup[area.area_id] = area;
}
this._areas = areaLookup;
}),
subscribeDeviceRegistry(this.hass.connection!, (devices) => {
const deviceLookup: { [deviceId: string]: DeviceRegistryEntry } = {};
for (const device of devices) {
deviceLookup[device.id] = device;
}
this._devices = deviceLookup;
}),
subscribeEntityRegistry(this.hass.connection!, (entities) => {
this._entities = entities;
}),
];
}
protected render() {
if (!this._areas || !this._devices || !this._entities) {
return html``;
}
return html`<div class="mdc-chip-set items">
${ensureArray(this.value?.area_id)?.map((area_id) => {
const area = this._areas![area_id];
return this._renderChip(
"area_id",
area_id,
area?.name || area_id,
undefined,
mdiSofa
);
})}
${ensureArray(this.value?.device_id)?.map((device_id) => {
const device = this._devices![device_id];
return this._renderChip(
"device_id",
device_id,
device?.name || device_id,
undefined,
mdiDevices
);
})}
${ensureArray(this.value?.entity_id)?.map((entity_id) => {
const entity = this.hass.states[entity_id];
return this._renderChip(
"entity_id",
entity_id,
entity ? computeStateName(entity) : entity_id,
entity ? stateIcon(entity) : undefined
);
})}
</div>
${this._renderPicker()}
<div class="mdc-chip-set">
<div
class="mdc-chip area_id add"
.type=${"area_id"}
@click=${this._showPicker}
>
<div class="mdc-chip__ripple"></div>
<ha-svg-icon
class="mdc-chip__icon mdc-chip__icon--leading"
.path=${mdiPlus}
></ha-svg-icon>
<span role="gridcell">
<span role="button" tabindex="0" class="mdc-chip__primary-action">
<span class="mdc-chip__text"
>${this.hass.localize(
"ui.components.target-picker.add_area_id"
)}</span
>
</span>
</span>
</div>
<div
class="mdc-chip device_id add"
.type=${"device_id"}
@click=${this._showPicker}
>
<div class="mdc-chip__ripple"></div>
<ha-svg-icon
class="mdc-chip__icon mdc-chip__icon--leading"
.path=${mdiPlus}
></ha-svg-icon>
<span role="gridcell">
<span role="button" tabindex="0" class="mdc-chip__primary-action">
<span class="mdc-chip__text"
>${this.hass.localize(
"ui.components.target-picker.add_device_id"
)}</span
>
</span>
</span>
</div>
<div
class="mdc-chip entity_id add"
.type=${"entity_id"}
@click=${this._showPicker}
>
<div class="mdc-chip__ripple"></div>
<ha-svg-icon
class="mdc-chip__icon mdc-chip__icon--leading"
.path=${mdiPlus}
></ha-svg-icon>
<span role="gridcell">
<span role="button" tabindex="0" class="mdc-chip__primary-action">
<span class="mdc-chip__text"
>${this.hass.localize(
"ui.components.target-picker.add_entity_id"
)}</span
>
</span>
</span>
</div>
</div>`;
}
private async _showPicker(ev) {
this._addMode = ev.currentTarget.type;
await this.updateComplete;
setTimeout(() => {
this._inputElement?.open();
this._inputElement?.focus();
}, 0);
}
private _renderChip(
type: string,
id: string,
name: string,
icon?: string,
iconPath?: string
) {
return html`
<div
class="mdc-chip ${classMap({
[type]: true,
})}"
>
${iconPath
? html`<ha-svg-icon
class="mdc-chip__icon mdc-chip__icon--leading"
.path=${iconPath}
></ha-svg-icon>`
: ""}
${icon
? html`<ha-icon
class="mdc-chip__icon mdc-chip__icon--leading"
.icon=${icon}
></ha-icon>`
: ""}
<span role="gridcell">
<span role="button" tabindex="0" class="mdc-chip__primary-action">
<span class="mdc-chip__text">${name}</span>
</span>
</span>
${type === "entity_id"
? ""
: html` <span role="gridcell">
<mwc-icon-button
class="expand-btn mdc-chip__icon mdc-chip__icon--trailing"
tabindex="-1"
role="button"
.label=${"Expand"}
.id=${id}
.type=${type}
@click=${this._handleExpand}
>
<ha-svg-icon .path=${mdiUnfoldMoreVertical}></ha-svg-icon>
</mwc-icon-button>
<paper-tooltip class="expand" animation-delay="0"
>${this.hass.localize(
`ui.components.target-picker.expand_${type}`
)}</paper-tooltip
>
</span>`}
<span role="gridcell">
<mwc-icon-button
class="mdc-chip__icon mdc-chip__icon--trailing"
tabindex="-1"
role="button"
.label=${"Remove"}
.id=${id}
.type=${type}
@click=${this._handleRemove}
>
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
</mwc-icon-button>
<paper-tooltip animation-delay="0"
>${this.hass.localize(
`ui.components.target-picker.remove_${type}`
)}</paper-tooltip
>
</span>
</div>
`;
}
private _renderPicker() {
switch (this._addMode) {
case "area_id":
return html`<ha-area-picker
.hass=${this.hass}
id="input"
.type=${"area_id"}
.label=${this.hass.localize(
"ui.components.target-picker.add_area_id"
)}
no-add
.deviceFilter=${this.deviceFilter}
.entityFilter=${this.entityRegFilter}
.includeDeviceClasses=${this.includeDeviceClasses}
.includeDomains=${this.includeDomains}
@value-changed=${this._targetPicked}
></ha-area-picker>`;
case "device_id":
return html`<ha-device-picker
.hass=${this.hass}
id="input"
.type=${"device_id"}
.label=${this.hass.localize(
"ui.components.target-picker.add_device_id"
)}
.deviceFilter=${this.deviceFilter}
.entityFilter=${this.entityRegFilter}
.includeDeviceClasses=${this.includeDeviceClasses}
.includeDomains=${this.includeDomains}
@value-changed=${this._targetPicked}
></ha-device-picker>`;
case "entity_id":
return html`<ha-entity-picker
.hass=${this.hass}
id="input"
.type=${"entity_id"}
.label=${this.hass.localize(
"ui.components.target-picker.add_entity_id"
)}
.entityFilter=${this.entityFilter}
.includeDeviceClasses=${this.includeDeviceClasses}
.includeDomains=${this.includeDomains}
@value-changed=${this._targetPicked}
></ha-entity-picker>`;
}
return html``;
}
private _targetPicked(ev) {
ev.stopPropagation();
if (!ev.detail.value) {
return;
}
const value = ev.detail.value;
const target = ev.currentTarget;
target.value = "";
this._addMode = undefined;
fireEvent(this, "value-changed", {
value: this.value
? {
...this.value,
[target.type]: this.value[target.type]
? [...ensureArray(this.value[target.type]), value]
: value,
}
: { [target.type]: value },
});
}
private _handleExpand(ev) {
const target = ev.currentTarget as any;
const newDevices: string[] = [];
const newEntities: string[] = [];
if (target.type === "area_id") {
Object.values(this._devices!).forEach((device) => {
if (
device.area_id === target.id &&
!this.value!.device_id?.includes(device.id) &&
this._deviceMeetsFilter(device)
) {
newDevices.push(device.id);
}
});
this._entities!.forEach((entity) => {
if (
entity.area_id === target.id &&
!this.value!.entity_id?.includes(entity.entity_id) &&
this._entityRegMeetsFilter(entity)
) {
newEntities.push(entity.entity_id);
}
});
} else if (target.type === "device_id") {
this._entities!.forEach((entity) => {
if (
entity.device_id === target.id &&
!this.value!.entity_id?.includes(entity.entity_id) &&
this._entityRegMeetsFilter(entity)
) {
newEntities.push(entity.entity_id);
}
});
} else {
return;
}
let value = this.value;
if (newEntities.length) {
value = this._addItems(value, "entity_id", newEntities);
}
if (newDevices.length) {
value = this._addItems(value, "device_id", newDevices);
}
value = this._removeItem(value, target.type, target.id);
fireEvent(this, "value-changed", { value });
}
private _handleRemove(ev) {
const target = ev.currentTarget as any;
fireEvent(this, "value-changed", {
value: this._removeItem(this.value, target.type, target.id),
});
}
private _addItems(
value: this["value"],
type: string,
ids: string[]
): this["value"] {
return {
...value,
[type]: value![type] ? ensureArray(value![type])!.concat(ids) : ids,
};
}
private _removeItem(
value: this["value"],
type: string,
id: string
): this["value"] {
const newVal = ensureArray(value![type])!.filter((val) => val !== id);
if (newVal.length) {
return {
...value,
[type]: newVal,
};
}
const val = { ...value }!;
delete val[type];
if (Object.keys(val).length) {
return val;
}
return undefined;
}
private _deviceMeetsFilter(device: DeviceRegistryEntry): boolean {
const devEntities = this._entities?.filter(
(entity) => entity.device_id === device.id
);
if (this.includeDomains) {
if (!devEntities || !devEntities.length) {
return false;
}
if (
!devEntities.some((entity) =>
this.includeDomains!.includes(computeDomain(entity.entity_id))
)
) {
return false;
}
}
if (this.includeDeviceClasses) {
if (!devEntities || !devEntities.length) {
return false;
}
if (
!devEntities.some((entity) => {
const stateObj = this.hass.states[entity.entity_id];
if (!stateObj) {
return false;
}
return (
stateObj.attributes.device_class &&
this.includeDeviceClasses!.includes(
stateObj.attributes.device_class
)
);
})
) {
return false;
}
}
if (this.deviceFilter) {
return this.deviceFilter(device);
}
return true;
}
private _entityRegMeetsFilter(entity: EntityRegistryEntry): boolean {
if (
this.includeDomains &&
!this.includeDomains.includes(computeDomain(entity.entity_id))
) {
return false;
}
if (this.includeDeviceClasses) {
const stateObj = this.hass.states[entity.entity_id];
if (!stateObj) {
return false;
}
if (
!stateObj.attributes.device_class ||
!this.includeDeviceClasses!.includes(stateObj.attributes.device_class)
) {
return false;
}
}
if (this.entityRegFilter) {
return this.entityRegFilter(entity);
}
return true;
}
static get styles(): CSSResult {
return css`
${unsafeCSS(chipStyles)}
.mdc-chip {
color: var(--primary-text-color);
}
.items {
z-index: 2;
}
.mdc-chip.add {
color: rgba(0, 0, 0, 0.87);
}
.mdc-chip:not(.add) {
cursor: default;
}
.mdc-chip mwc-icon-button {
--mdc-icon-button-size: 24px;
display: flex;
align-items: center;
outline: none;
}
.mdc-chip mwc-icon-button ha-svg-icon {
border-radius: 50%;
background: var(--secondary-text-color);
}
.mdc-chip__icon.mdc-chip__icon--trailing {
width: 16px;
height: 16px;
--mdc-icon-size: 14px;
color: var(--card-background-color);
}
.mdc-chip__icon--leading {
display: flex;
align-items: center;
justify-content: center;
--mdc-icon-size: 20px;
border-radius: 50%;
padding: 6px;
margin-left: -14px !important;
}
.expand-btn {
margin-right: 0;
}
.mdc-chip.area_id:not(.add) {
border: 2px solid #fed6a4;
background: var(--card-background-color);
}
.mdc-chip.area_id:not(.add) .mdc-chip__icon--leading,
.mdc-chip.area_id.add {
background: #fed6a4;
}
.mdc-chip.device_id:not(.add) {
border: 2px solid #a8e1fb;
background: var(--card-background-color);
}
.mdc-chip.device_id:not(.add) .mdc-chip__icon--leading,
.mdc-chip.device_id.add {
background: #a8e1fb;
}
.mdc-chip.entity_id:not(.add) {
border: 2px solid #d2e7b9;
background: var(--card-background-color);
}
.mdc-chip.entity_id:not(.add) .mdc-chip__icon--leading,
.mdc-chip.entity_id.add {
background: #d2e7b9;
}
.mdc-chip:hover {
z-index: 5;
}
paper-tooltip.expand {
min-width: 200px;
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-target-picker": HaTargetPicker;
}
}

View File

@@ -6,7 +6,7 @@ import { navigate } from "../common/navigate";
import { Context, HomeAssistant } from "../types";
import { BlueprintInput } from "./blueprint";
import { DeviceCondition, DeviceTrigger } from "./device_automation";
import { Action } from "./script";
import { Action, MODES } from "./script";
export interface AutomationEntity extends HassEntityBase {
attributes: HassEntityAttributeBase & {
@@ -26,7 +26,7 @@ export interface ManualAutomationConfig {
trigger: Trigger[];
condition?: Condition[];
action: Action[];
mode?: "single" | "restart" | "queued" | "parallel";
mode?: typeof MODES[number];
max?: number;
}

View File

@@ -17,6 +17,7 @@ export interface DeviceRegistryEntry {
area_id?: string;
name_by_user?: string;
entry_type: "service" | null;
disabled_by: string | null;
}
export interface DeviceEntityLookup {
@@ -26,6 +27,7 @@ export interface DeviceEntityLookup {
export interface DeviceRegistryEntryMutableParams {
area_id?: string | null;
name_by_user?: string | null;
disabled_by?: string | null;
}
export const fallbackDeviceName = (

View File

@@ -7,13 +7,13 @@ import { navigate } from "../common/navigate";
import { HomeAssistant } from "../types";
import { Condition, Trigger } from "./automation";
export const MODES = ["single", "restart", "queued", "parallel"];
export const MODES = ["single", "restart", "queued", "parallel"] as const;
export const MODES_MAX = ["queued", "parallel"];
export interface ScriptEntity extends HassEntityBase {
attributes: HassEntityAttributeBase & {
last_triggered: string;
mode: "single" | "restart" | "queued" | "parallel";
mode: typeof MODES[number];
current?: number;
max?: number;
};
@@ -23,7 +23,7 @@ export interface ScriptConfig {
alias: string;
sequence: Action[];
icon?: string;
mode?: "single" | "restart" | "queued" | "parallel";
mode?: typeof MODES[number];
max?: number;
}

View File

@@ -2,9 +2,11 @@ export type Selector =
| EntitySelector
| DeviceSelector
| AreaSelector
| TargetSelector
| NumberSelector
| BooleanSelector
| TimeSelector;
| TimeSelector
| ActionSelector;
export interface EntitySelector {
entity: {
@@ -19,13 +21,41 @@ export interface DeviceSelector {
integration?: string;
manufacturer?: string;
model?: string;
entity?: EntitySelector["entity"];
entity?: {
domain?: EntitySelector["entity"]["domain"];
device_class?: EntitySelector["entity"]["device_class"];
};
};
}
export interface AreaSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
area: {};
area: {
entity?: {
integration?: EntitySelector["entity"]["integration"];
domain?: EntitySelector["entity"]["domain"];
device_class?: EntitySelector["entity"]["device_class"];
};
device?: {
integration?: DeviceSelector["device"]["integration"];
manufacturer?: DeviceSelector["device"]["manufacturer"];
model?: DeviceSelector["device"]["model"];
};
};
}
export interface TargetSelector {
target: {
entity?: {
integration?: EntitySelector["entity"]["integration"];
domain?: EntitySelector["entity"]["domain"];
device_class?: EntitySelector["entity"]["device_class"];
};
device?: {
integration?: DeviceSelector["device"]["integration"];
manufacturer?: DeviceSelector["device"]["manufacturer"];
model?: DeviceSelector["device"]["model"];
};
};
}
export interface NumberSelector {
@@ -47,3 +77,8 @@ export interface TimeSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
time: {};
}
export interface ActionSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
action: {};
}

5
src/data/target.ts Normal file
View File

@@ -0,0 +1,5 @@
export interface Target {
entity_id?: string[];
device_id?: string[];
area_id?: string[];
}

View File

@@ -20,6 +20,7 @@ export interface User {
export interface UpdateUserParams {
name?: User["name"];
is_active?: User["is_active"];
group_ids?: User["group_ids"];
}

View File

@@ -17,6 +17,7 @@ import { PolymerChangedEvent } from "../../../polymer-types";
import { haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
import { AreaRegistryDetailDialogParams } from "./show-dialog-area-registry-detail";
import { navigate } from "../../../common/navigate";
class DialogAreaDetail extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -154,6 +155,8 @@ class DialogAreaDetail extends LitElement {
} finally {
this._submitting = false;
}
navigate(this, "/config/areas/dashboard");
}
static get styles(): CSSResult[] {

View File

@@ -39,7 +39,7 @@ export class HaWaitForTriggerAction extends LitElement
)}
>
<ha-switch
.checked=${continue_on_timeout}
.checked=${continue_on_timeout ?? true}
@change=${this._continueChanged}
></ha-switch>
</ha-formfield>

View File

@@ -18,13 +18,9 @@ import "@polymer/paper-input/paper-textarea";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light";
import "../../../components/entity/ha-entity-toggle";
import "@material/mwc-button/mwc-button";
import "./trigger/ha-automation-trigger";
import "./condition/ha-automation-condition";
import "./action/ha-automation-action";
import { fireEvent } from "../../../common/dom/fire_event";
import { haStyle } from "../../../resources/styles";
import { HassEntity } from "home-assistant-js-websocket";
import { navigate } from "../../../common/navigate";
import {
BlueprintOrError,
Blueprints,
@@ -63,7 +59,7 @@ export class HaBlueprintAutomationEditor extends LitElement {
protected render() {
const blueprint = this._blueprint;
return html`<ha-config-section .isWide=${this.isWide}>
return html`<ha-config-section vertical .isWide=${this.isWide}>
${!this.narrow
? html` <span slot="header">${this.config.alias}</span> `
: ""}
@@ -119,7 +115,7 @@ export class HaBlueprintAutomationEditor extends LitElement {
</ha-card>
</ha-config-section>
<ha-config-section .isWide=${this.isWide}>
<ha-config-section vertical .isWide=${this.isWide}>
<span slot="header"
>${this.hass.localize(
"ui.panel.config.automation.editor.blueprint.header"
@@ -144,11 +140,6 @@ export class HaBlueprintAutomationEditor extends LitElement {
"ui.panel.config.automation.editor.blueprint.no_blueprints"
)
: html`<ha-circular-progress active></ha-circular-progress>`}
<mwc-button @click=${this._navigateBlueprints}>
${this.hass.localize(
"ui.panel.config.automation.editor.blueprint.manage_blueprints"
)}
</mwc-button>
</div>
${this.config.use_blueprint.path
@@ -157,41 +148,37 @@ export class HaBlueprintAutomationEditor extends LitElement {
There is an error in this Blueprint: ${blueprint.error}
</p>`
: html`${blueprint?.metadata.description
? html`<p>${blueprint.metadata.description}</p>`
? html`<p class="card-content pre-line">
${blueprint.metadata.description}
</p>`
: ""}
${blueprint?.metadata?.input &&
Object.keys(blueprint.metadata.input).length
? html`<h3>
${this.hass.localize(
"ui.panel.config.automation.editor.blueprint.inputs"
)}
</h3>
${Object.entries(blueprint.metadata.input).map(
([key, value]) =>
html`<ha-settings-row .narrow=${this.narrow}>
<span slot="heading">${value?.name || key}</span>
<span slot="description"
>${value?.description}</span
>
${value?.selector
? html`<ha-selector
.hass=${this.hass}
.selector=${value.selector}
.key=${key}
.value=${(this.config.use_blueprint.input &&
this.config.use_blueprint.input[key]) ||
value?.default}
@value-changed=${this._inputChanged}
></ha-selector>`
: html`<paper-input
.key=${key}
.value=${this.config.use_blueprint.input &&
this.config.use_blueprint.input[key]}
@value-changed=${this._inputChanged}
no-label-float
></paper-input>`}
</ha-settings-row>`
)}`
? Object.entries(blueprint.metadata.input).map(
([key, value]) =>
html`<ha-settings-row .narrow=${this.narrow}>
<span slot="heading">${value?.name || key}</span>
<span slot="description">${value?.description}</span>
${value?.selector
? html`<ha-selector
.hass=${this.hass}
.selector=${value.selector}
.key=${key}
.value=${(this.config.use_blueprint.input &&
this.config.use_blueprint.input[key]) ||
value?.default}
@value-changed=${this._inputChanged}
></ha-selector>`
: html`<paper-input
.key=${key}
required
.value=${this.config.use_blueprint.input &&
this.config.use_blueprint.input[key]}
@value-changed=${this._inputChanged}
no-label-float
></paper-input>`}
</ha-settings-row>`
)
: html`<p class="padding">
${this.hass.localize(
"ui.panel.config.automation.editor.blueprint.no_inputs"
@@ -237,12 +224,18 @@ export class HaBlueprintAutomationEditor extends LitElement {
) {
return;
}
const input = { ...this.config.use_blueprint.input, [key]: value };
if (value === "" || value === undefined) {
delete input[key];
}
fireEvent(this, "value-changed", {
value: {
...this.config!,
use_blueprint: {
...this.config.use_blueprint,
input: { ...this.config.use_blueprint.input, [key]: value },
input,
},
},
});
@@ -267,25 +260,18 @@ export class HaBlueprintAutomationEditor extends LitElement {
});
}
private _navigateBlueprints() {
navigate(this, "/config/blueprint");
}
static get styles(): CSSResult[] {
return [
haStyle,
css`
ha-card {
overflow: hidden;
}
.padding {
padding: 16px;
}
.pre-line {
white-space: pre-line;
}
.blueprint-picker-container {
padding: 16px;
display: flex;
align-items: center;
justify-content: space-between;
}
h3 {
margin: 16px;
@@ -304,10 +290,10 @@ export class HaBlueprintAutomationEditor extends LitElement {
border-top: 1px solid var(--divider-color);
}
:host(:not([narrow])) ha-settings-row paper-input {
width: 50%;
width: 60%;
}
:host(:not([narrow])) ha-settings-row ha-selector {
width: 50%;
width: 60%;
}
`,
];

View File

@@ -206,6 +206,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
? html`<blueprint-automation-editor
.hass=${this.hass}
.narrow=${this.narrow}
.isWide=${this.isWide}
.stateObj=${stateObj}
.config=${this._config}
@value-changed=${this._valueChanged}
@@ -213,6 +214,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
: html`<manual-automation-editor
.hass=${this.hass}
.narrow=${this.narrow}
.isWide=${this.isWide}
.stateObj=${stateObj}
.config=${this._config}
@value-changed=${this._valueChanged}

View File

@@ -12,6 +12,7 @@ import {
internalProperty,
query,
TemplateResult,
css,
} from "lit-element";
import "../../../components/ha-dialog";
import { haStyleDialog } from "../../../resources/styles";
@@ -73,7 +74,9 @@ class DialogImportBlueprint extends LitElement {
this._result.blueprint.metadata.domain
)}
<br />
${this._result.blueprint.metadata.description}
<p class="pre-line">
${this._result.blueprint.metadata.description}
</p>
${this._result.validation_errors
? html`
<p class="error">
@@ -199,8 +202,15 @@ class DialogImportBlueprint extends LitElement {
}
}
static get styles(): CSSResult {
return haStyleDialog;
static get styles(): CSSResult[] {
return [
haStyleDialog,
css`
.pre-line {
white-space: pre-line;
}
`,
];
}
}

View File

@@ -1,6 +1,6 @@
import "../../../components/ha-fab";
import "@material/mwc-icon-button";
import { mdiPlus, mdiHelpCircle, mdiDelete, mdiRobot } from "@mdi/js";
import { mdiHelpCircle, mdiDelete, mdiRobot, mdiDownload } from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
import {
CSSResult,
@@ -112,7 +112,6 @@ class HaBlueprintOverview extends LitElement {
create: {
title: "",
type: narrow ? "icon-button" : undefined,
width: narrow ? undefined : "180px",
template: (_, blueprint: any) =>
blueprint.error
? ""
@@ -126,8 +125,9 @@ class HaBlueprintOverview extends LitElement {
"ui.panel.config.blueprint.overview.use_blueprint"
)}
@click=${(ev) => this._createNew(ev)}
><ha-svg-icon .path=${mdiRobot}></ha-svg-icon
></mwc-icon-button>`
>
<ha-svg-icon .path=${mdiRobot}></ha-svg-icon>
</mwc-icon-button>`
: html`<mwc-button
.blueprint=${blueprint}
@click=${(ev) => this._createNew(ev)}
@@ -182,7 +182,7 @@ class HaBlueprintOverview extends LitElement {
extended
@click=${this._addBlueprint}
>
<ha-svg-icon slot="icon" .path=${mdiPlus}></ha-svg-icon>
<ha-svg-icon slot="icon" .path=${mdiDownload}></ha-svg-icon>
</ha-fab>
</hass-tabs-subpage-data-table>
`;
@@ -195,7 +195,10 @@ class HaBlueprintOverview extends LitElement {
${this.hass.localize("ui.panel.config.blueprint.overview.introduction")}
<p>
<a
href="${documentationUrl(this.hass, "/docs/blueprint/editor/")}"
href="${documentationUrl(
this.hass,
"/docs/automation/using_blueprints/"
)}"
target="_blank"
rel="noreferrer"
>

View File

@@ -8,7 +8,6 @@ import {
html,
LitElement,
property,
internalProperty,
PropertyValues,
TemplateResult,
} from "lit-element";
@@ -31,7 +30,7 @@ export class HaDeviceEntitiesCard extends LitElement {
@property() public entities!: EntityRegistryStateEntry[];
@internalProperty() private _showDisabled = false;
@property() public showDisabled = false;
private _entityRows: Array<LovelaceRow | HuiErrorCard> = [];
@@ -68,7 +67,7 @@ export class HaDeviceEntitiesCard extends LitElement {
})}
</div>
${disabledEntities.length
? !this._showDisabled
? !this.showDisabled
? html`
<button
class="show-more"
@@ -119,7 +118,7 @@ export class HaDeviceEntitiesCard extends LitElement {
}
private _toggleShowDisabled() {
this._showDisabled = !this._showDisabled;
this.showDisabled = !this.showDisabled;
}
private _renderEntity(entry: EntityRegistryStateEntry): TemplateResult {
@@ -227,3 +226,9 @@ export class HaDeviceEntitiesCard extends LitElement {
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-device-entities-card": HaDeviceEntitiesCard;
}
}

View File

@@ -19,10 +19,11 @@ import {
import { DeviceRegistryDetailDialogParams } from "./show-dialog-device-registry-detail";
import { HomeAssistant } from "../../../../types";
import type { HaSwitch } from "../../../../components/ha-switch";
import { PolymerChangedEvent } from "../../../../polymer-types";
import { computeDeviceName } from "../../../../data/device_registry";
import { fireEvent } from "../../../../common/dom/fire_event";
import { haStyleDialog } from "../../../../resources/styles";
import { haStyle, haStyleDialog } from "../../../../resources/styles";
@customElement("dialog-device-registry-detail")
class DialogDeviceRegistryDetail extends LitElement {
@@ -36,6 +37,8 @@ class DialogDeviceRegistryDetail extends LitElement {
@internalProperty() private _areaId?: string;
@internalProperty() private _disabledBy!: string | null;
@internalProperty() private _submitting?: boolean;
public async showDialog(
@@ -45,6 +48,7 @@ class DialogDeviceRegistryDetail extends LitElement {
this._error = undefined;
this._nameByUser = this._params.device.name_by_user || "";
this._areaId = this._params.device.area_id;
this._disabledBy = this._params.device.disabled_by;
await this.updateComplete;
}
@@ -80,6 +84,32 @@ class DialogDeviceRegistryDetail extends LitElement {
.value=${this._areaId}
@value-changed=${this._areaPicked}
></ha-area-picker>
<div class="row">
<ha-switch
.checked=${!this._disabledBy}
@change=${this._disabledByChanged}
>
</ha-switch>
<div>
<div>
${this.hass.localize("ui.panel.config.devices.enabled_label")}
</div>
<div class="secondary">
${this._disabledBy && this._disabledBy !== "user"
? this.hass.localize(
"ui.panel.config.devices.enabled_cause",
"cause",
this.hass.localize(
`config_entry.disabled_by.${this._disabledBy}`
)
)
: ""}
${this.hass.localize(
"ui.panel.config.devices.enabled_description"
)}
</div>
</div>
</div>
</div>
</div>
<mwc-button
@@ -109,12 +139,17 @@ class DialogDeviceRegistryDetail extends LitElement {
this._areaId = event.detail.value;
}
private _disabledByChanged(ev: Event): void {
this._disabledBy = (ev.target as HaSwitch).checked ? null : "user";
}
private async _updateEntry(): Promise<void> {
this._submitting = true;
try {
await this._params!.updateEntry({
name_by_user: this._nameByUser.trim() || null,
area_id: this._areaId || null,
disabled_by: this._disabledBy || null,
});
this._params = undefined;
} catch (err) {
@@ -128,6 +163,7 @@ class DialogDeviceRegistryDetail extends LitElement {
static get styles(): CSSResult[] {
return [
haStyle,
haStyleDialog,
css`
.form {
@@ -139,6 +175,15 @@ class DialogDeviceRegistryDetail extends LitElement {
.error {
color: var(--error-color);
}
ha-switch {
margin-right: 16px;
}
.row {
margin-top: 8px;
color: var(--primary-text-color);
display: flex;
align-items: center;
}
`,
];
}

View File

@@ -46,6 +46,7 @@ import "./device-detail/ha-device-entities-card";
import "./device-detail/ha-device-info-card";
import { showDeviceAutomationDialog } from "./device-detail/show-dialog-device-automation";
import { brandsUrl } from "../../../util/brands-url";
import { haStyle } from "../../../resources/styles";
export interface EntityRegistryStateEntry extends EntityRegistryEntry {
stateName?: string | null;
@@ -246,6 +247,28 @@ export class HaConfigDevicePage extends LitElement {
.devices=${this.devices}
.device=${device}
>
${
device.disabled_by
? html`
<div>
<p class="warning">
${this.hass.localize(
"ui.panel.config.devices.enabled_cause",
"cause",
this.hass.localize(
`ui.panel.config.devices.disabled_by.${device.disabled_by}`
)
)}
</p>
</div>
<div class="card-actions" slot="actions">
<mwc-button unelevated @click=${this._enableDevice}>
${this.hass.localize("ui.common.enable")}
</mwc-button>
</div>
`
: html``
}
${this._renderIntegrationInfo(device, integrations)}
</ha-device-info-card>
@@ -255,6 +278,7 @@ export class HaConfigDevicePage extends LitElement {
<ha-device-entities-card
.hass=${this.hass}
.entities=${entities}
.showDisabled=${device.disabled_by !== null}
>
</ha-device-entities-card>
`
@@ -272,9 +296,14 @@ export class HaConfigDevicePage extends LitElement {
)}
<ha-icon-button
@click=${this._showAutomationDialog}
title=${this.hass.localize(
"ui.panel.config.devices.automation.create"
)}
.disabled=${device.disabled_by}
title=${device.disabled_by
? this.hass.localize(
"ui.panel.config.devices.automation.create_disabled"
)
: this.hass.localize(
"ui.panel.config.devices.automation.create"
)}
icon="hass:plus-circle"
></ha-icon-button>
</h1>
@@ -342,9 +371,16 @@ export class HaConfigDevicePage extends LitElement {
<ha-icon-button
@click=${this._createScene}
title=${this.hass.localize(
"ui.panel.config.devices.scene.create"
)}
.disabled=${device.disabled_by}
title=${
device.disabled_by
? this.hass.localize(
"ui.panel.config.devices.scene.create_disabled"
)
: this.hass.localize(
"ui.panel.config.devices.scene.create"
)
}
icon="hass:plus-circle"
></ha-icon-button>
</h1>
@@ -415,9 +451,14 @@ export class HaConfigDevicePage extends LitElement {
)}
<ha-icon-button
@click=${this._showScriptDialog}
title=${this.hass.localize(
"ui.panel.config.devices.script.create"
)}
.disabled=${device.disabled_by}
title=${device.disabled_by
? this.hass.localize(
"ui.panel.config.devices.script.create_disabled"
)
: this.hass.localize(
"ui.panel.config.devices.script.create"
)}
icon="hass:plus-circle"
></ha-icon-button>
</h1>
@@ -632,128 +673,137 @@ export class HaConfigDevicePage extends LitElement {
});
}
static get styles(): CSSResult {
return css`
.container {
display: flex;
flex-wrap: wrap;
margin: auto;
max-width: 1000px;
margin-top: 32px;
margin-bottom: 32px;
}
private async _enableDevice(): Promise<void> {
await updateDeviceRegistryEntry(this.hass, this.deviceId, {
disabled_by: null,
});
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
}
static get styles(): CSSResult[] {
return [
haStyle,
css`
.container {
display: flex;
flex-wrap: wrap;
margin: auto;
max-width: 1000px;
margin-top: 32px;
margin-bottom: 32px;
}
.card-header ha-icon-button {
margin-right: -8px;
color: var(--primary-color);
height: auto;
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.device-info {
padding: 16px;
}
.card-header ha-icon-button {
margin-right: -8px;
color: var(--primary-color);
height: auto;
}
.show-more {
}
.device-info {
padding: 16px;
}
h1 {
margin: 0;
font-family: var(--paper-font-headline_-_font-family);
-webkit-font-smoothing: var(
--paper-font-headline_-_-webkit-font-smoothing
);
font-size: var(--paper-font-headline_-_font-size);
font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height);
opacity: var(--dark-primary-opacity);
}
.show-more {
}
.header {
display: flex;
justify-content: space-between;
}
h1 {
margin: 0;
font-family: var(--paper-font-headline_-_font-family);
-webkit-font-smoothing: var(
--paper-font-headline_-_-webkit-font-smoothing
);
font-size: var(--paper-font-headline_-_font-size);
font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height);
opacity: var(--dark-primary-opacity);
}
.column,
.fullwidth {
padding: 8px;
box-sizing: border-box;
}
.column {
width: 33%;
flex-grow: 1;
}
.fullwidth {
width: 100%;
flex-grow: 1;
}
.header {
display: flex;
justify-content: space-between;
}
.header-right {
align-self: center;
}
.column,
.fullwidth {
padding: 8px;
box-sizing: border-box;
}
.column {
width: 33%;
flex-grow: 1;
}
.fullwidth {
width: 100%;
flex-grow: 1;
}
.header-right img {
height: 30px;
}
.header-right {
align-self: center;
}
.header-right {
display: flex;
}
.header-right img {
height: 30px;
}
.header-right:first-child {
width: 100%;
justify-content: flex-end;
}
.header-right {
display: flex;
}
.header-right > *:not(:first-child) {
margin-left: 16px;
}
.header-right:first-child {
width: 100%;
justify-content: flex-end;
}
.battery {
align-self: center;
align-items: center;
display: flex;
}
.header-right > *:not(:first-child) {
margin-left: 16px;
}
.column > *:not(:first-child) {
margin-top: 16px;
}
.battery {
align-self: center;
align-items: center;
display: flex;
}
:host([narrow]) .column {
width: 100%;
}
.column > *:not(:first-child) {
margin-top: 16px;
}
:host([narrow]) .container {
margin-top: 0;
}
:host([narrow]) .column {
width: 100%;
}
paper-item {
cursor: pointer;
font-size: var(--paper-font-body1_-_font-size);
}
:host([narrow]) .container {
margin-top: 0;
}
paper-item.no-link {
cursor: default;
}
paper-item {
cursor: pointer;
font-size: var(--paper-font-body1_-_font-size);
}
a {
text-decoration: none;
color: var(--primary-color);
}
paper-item.no-link {
cursor: default;
}
ha-card {
padding-bottom: 8px;
}
a {
text-decoration: none;
color: var(--primary-color);
}
ha-card a {
color: var(--primary-text-color);
}
`;
ha-card {
padding-bottom: 8px;
}
ha-card a {
color: var(--primary-text-color);
}
`,
];
}
}

View File

@@ -1,5 +1,9 @@
import { mdiPlus } from "@mdi/js";
import { mdiPlus, mdiFilterVariant, mdiCancel } from "@mdi/js";
import "@material/mwc-list/mwc-list-item";
import "@polymer/paper-tooltip/paper-tooltip";
import {
css,
CSSResult,
customElement,
html,
internalProperty,
@@ -7,7 +11,9 @@ import {
property,
TemplateResult,
} from "lit-element";
import { classMap } from "lit-html/directives/class-map";
import memoizeOne from "memoize-one";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import { HASSDomEvent } from "../../../common/dom/fire_event";
import { navigate } from "../../../common/navigate";
import { LocalizeFunc } from "../../../common/translations/localize";
@@ -18,6 +24,7 @@ import {
RowClickedEvent,
} from "../../../components/data-table/ha-data-table";
import "../../../components/entity/ha-battery-icon";
import "../../../components/ha-button-menu";
import { AreaRegistryEntry } from "../../../data/area_registry";
import { ConfigEntry } from "../../../data/config_entries";
import {
@@ -34,6 +41,7 @@ import { domainToName } from "../../../data/integration";
import "../../../layouts/hass-tabs-subpage-data-table";
import { HomeAssistant, Route } from "../../../types";
import { configSections } from "../ha-panel-config";
import { haStyle } from "../../../resources/styles";
interface DeviceRowData extends DeviceRegistryEntry {
device?: DeviceRowData;
@@ -64,6 +72,12 @@ export class HaConfigDeviceDashboard extends LitElement {
window.location.search
);
@internalProperty() private _showDisabled = false;
@internalProperty() private _filter = "";
@internalProperty() private _numHiddenDevices = 0;
private _activeFilters = memoizeOne(
(
entries: ConfigEntry[],
@@ -74,6 +88,10 @@ export class HaConfigDeviceDashboard extends LitElement {
filters.forEach((value, key) => {
switch (key) {
case "config_entry": {
// If we are requested to show the devices for a given config entry,
// also show the disabled ones by default.
this._showDisabled = true;
const configEntry = entries.find(
(entry) => entry.entry_id === value
);
@@ -105,6 +123,7 @@ export class HaConfigDeviceDashboard extends LitElement {
entities: EntityRegistryEntry[],
areas: AreaRegistryEntry[],
filters: URLSearchParams,
showDisabled: boolean,
localize: LocalizeFunc
) => {
// Some older installations might have devices pointing at invalid entryIDs
@@ -117,6 +136,9 @@ export class HaConfigDeviceDashboard extends LitElement {
deviceLookup[device.id] = device;
}
// If nothing gets filtered, this is our correct count of devices
let startLength = outputDevices.length;
const deviceEntityLookup: DeviceEntityLookup = {};
for (const entity of entities) {
if (!entity.device_id) {
@@ -145,6 +167,7 @@ export class HaConfigDeviceDashboard extends LitElement {
outputDevices = outputDevices.filter((device) =>
device.config_entries.includes(value)
);
startLength = outputDevices.length;
const configEntry = entries.find((entry) => entry.entry_id === value);
if (configEntry) {
filterDomains.push(configEntry.domain);
@@ -152,6 +175,10 @@ export class HaConfigDeviceDashboard extends LitElement {
}
});
if (!showDisabled) {
outputDevices = outputDevices.filter((device) => !device.disabled_by);
}
outputDevices = outputDevices.map((device) => {
return {
...device,
@@ -182,16 +209,19 @@ export class HaConfigDeviceDashboard extends LitElement {
};
});
this._numHiddenDevices = startLength - outputDevices.length;
return { devicesOutput: outputDevices, filteredDomains: filterDomains };
}
);
private _columns = memoizeOne(
(narrow: boolean): DataTableColumnContainer => {
(narrow: boolean, showDisabled: boolean): DataTableColumnContainer => {
const columns: DataTableColumnContainer = narrow
? {
name: {
title: "Device",
title: this.hass.localize(
"ui.panel.config.devices.data_table.device"
),
sortable: true,
filterable: true,
direction: "asc",
@@ -277,6 +307,24 @@ export class HaConfigDeviceDashboard extends LitElement {
: html` - `;
},
};
if (showDisabled) {
columns.disabled_by = {
title: "",
type: "icon",
template: (disabled_by) =>
disabled_by
? html`<div
tabindex="0"
style="display:inline-block; position: relative;"
>
<ha-svg-icon .path=${mdiCancel}></ha-svg-icon>
<paper-tooltip animation-delay="0" position="left">
${this.hass.localize("ui.panel.config.devices.disabled")}
</paper-tooltip>
</div>`
: "",
};
}
return columns;
}
);
@@ -298,9 +346,119 @@ export class HaConfigDeviceDashboard extends LitElement {
this.entities,
this.areas,
this._searchParms,
this._showDisabled,
this.hass.localize
);
const includeZHAFab = filteredDomains.includes("zha");
const activeFilters = this._activeFilters(
this.entries,
this._searchParms,
this.hass.localize
);
const headerToolbar = html`
<search-input
no-label-float
no-underline
@value-changed=${this._handleSearchChange}
.filter=${this._filter}
.label=${this.hass.localize("ui.panel.config.devices.picker.search")}
></search-input
>${activeFilters
? html`<div class="active-filters">
${this.narrow
? html` <div>
<ha-icon icon="hass:filter-variant"></ha-icon>
<paper-tooltip animation-delay="0" position="left">
${this.hass.localize(
"ui.panel.config.filtering.filtering_by"
)}
${activeFilters.join(", ")}
${this._numHiddenDevices
? "(" +
this.hass.localize(
"ui.panel.config.devices.picker.filter.hidden_devices",
"number",
this._numHiddenDevices
) +
")"
: ""}
</paper-tooltip>
</div>`
: `${this.hass.localize(
"ui.panel.config.filtering.filtering_by"
)} ${activeFilters.join(", ")}
${
this._numHiddenDevices
? "(" +
this.hass.localize(
"ui.panel.config.devices.picker.filter.hidden_devices",
"number",
this._numHiddenDevices
) +
")"
: ""
}
`}
<mwc-button @click=${this._clearFilter}
>${this.hass.localize(
"ui.panel.config.filtering.clear"
)}</mwc-button
>
</div>`
: ""}
${this._numHiddenDevices && !activeFilters
? html`<div class="active-filters">
${this.narrow
? html` <div>
<ha-icon icon="hass:filter-variant"></ha-icon>
<paper-tooltip animation-delay="0" position="left">
${this.hass.localize(
"ui.panel.config.devices.picker.filter.hidden_devices",
"number",
this._numHiddenDevices
)}
</paper-tooltip>
</div>`
: `${this.hass.localize(
"ui.panel.config.devices.picker.filter.hidden_devices",
"number",
this._numHiddenDevices
)}`}
<mwc-button @click=${this._showAll}
>${this.hass.localize(
"ui.panel.config.devices.picker.filter.show_all"
)}</mwc-button
>
</div>`
: ""}
<ha-button-menu corner="BOTTOM_START" multi>
<mwc-icon-button
slot="trigger"
.label=${this.hass!.localize(
"ui.panel.config.devices.picker.filter.filter"
)}
.title=${this.hass!.localize(
"ui.panel.config.devices.picker.filter.filter"
)}
>
<ha-svg-icon .path=${mdiFilterVariant}></ha-svg-icon>
</mwc-icon-button>
<mwc-list-item
@request-selected="${this._showDisabledChanged}"
graphic="control"
.selected=${this._showDisabled}
>
<ha-checkbox
slot="graphic"
.checked=${this._showDisabled}
></ha-checkbox>
${this.hass!.localize(
"ui.panel.config.devices.picker.filter.show_disabled"
)}
</mwc-list-item>
</ha-button-menu>
`;
return html`
<hass-tabs-subpage-data-table
@@ -311,13 +469,9 @@ export class HaConfigDeviceDashboard extends LitElement {
: "/config"}
.tabs=${configSections.integrations}
.route=${this.route}
.columns=${this._columns(this.narrow)}
.columns=${this._columns(this.narrow, this._showDisabled)}
.data=${devicesOutput}
.activeFilters=${this._activeFilters(
this.entries,
this._searchParms,
this.hass.localize
)}
.filter=${this._filter}
@row-click=${this._handleRowClicked}
clickable
.hasFab=${includeZHAFab}
@@ -333,6 +487,15 @@ export class HaConfigDeviceDashboard extends LitElement {
</ha-fab>
</a>`
: html``}
<div
class=${classMap({
"search-toolbar": this.narrow,
"table-header": !this.narrow,
})}
slot="header"
>
${headerToolbar}
</div>
</hass-tabs-subpage-data-table>
`;
}
@@ -363,6 +526,136 @@ export class HaConfigDeviceDashboard extends LitElement {
const deviceId = ev.detail.id;
navigate(this, `/config/devices/device/${deviceId}`);
}
private _showDisabledChanged(ev: CustomEvent<RequestSelectedDetail>) {
if (ev.detail.source !== "property") {
return;
}
this._showDisabled = ev.detail.selected;
}
private _handleSearchChange(ev: CustomEvent) {
this._filter = ev.detail.value;
}
private _clearFilter() {
navigate(this, window.location.pathname, true);
}
private _showAll() {
this._showDisabled = true;
}
static get styles(): CSSResult[] {
return [
haStyle,
css`
hass-loading-screen {
--app-header-background-color: var(--sidebar-background-color);
--app-header-text-color: var(--sidebar-text-color);
}
a {
color: var(--primary-color);
}
h2 {
margin-top: 0;
font-family: var(--paper-font-headline_-_font-family);
-webkit-font-smoothing: var(
--paper-font-headline_-_-webkit-font-smoothing
);
font-size: var(--paper-font-headline_-_font-size);
font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height);
opacity: var(--dark-primary-opacity);
}
p {
font-family: var(--paper-font-subhead_-_font-family);
-webkit-font-smoothing: var(
--paper-font-subhead_-_-webkit-font-smoothing
);
font-weight: var(--paper-font-subhead_-_font-weight);
line-height: var(--paper-font-subhead_-_line-height);
}
ha-data-table {
width: 100%;
--data-table-border-width: 0;
}
:host(:not([narrow])) ha-data-table {
height: calc(100vh - 1px - var(--header-height));
display: block;
}
ha-button-menu {
margin-right: 8px;
}
.table-header {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid rgba(var(--rgb-primary-text-color), 0.12);
}
search-input {
margin-left: 16px;
flex-grow: 1;
position: relative;
top: 2px;
}
.search-toolbar search-input {
margin-left: 8px;
top: 1px;
}
.search-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
color: var(--secondary-text-color);
}
.search-toolbar ha-button-menu {
position: static;
}
.selected-txt {
font-weight: bold;
padding-left: 16px;
}
.table-header .selected-txt {
margin-top: 20px;
}
.search-toolbar .selected-txt {
font-size: 16px;
}
.header-btns > mwc-button,
.header-btns > ha-icon-button {
margin: 8px;
}
.active-filters {
color: var(--primary-text-color);
position: relative;
display: flex;
align-items: center;
padding: 2px 2px 2px 8px;
margin-left: 4px;
font-size: 14px;
}
.active-filters ha-icon {
color: var(--primary-color);
}
.active-filters mwc-button {
margin-left: 8px;
}
.active-filters::before {
background-color: var(--primary-color);
opacity: 0.12;
border-radius: 4px;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: "";
}
`,
];
}
}
declare global {

View File

@@ -111,10 +111,19 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
return html`
${!stateObj
? html`
<div class="container">
<div class="container warning">
${this.hass!.localize(
"ui.dialogs.entity_registry.editor.unavailable"
)}
${this._device?.disabled_by
? html`<br />${this.hass!.localize(
"ui.dialogs.entity_registry.editor.device_disabled"
)}<br /><mwc-button @click=${this._openDeviceSettings}>
${this.hass!.localize(
"ui.dialogs.entity_registry.editor.open_device_settings"
)}
</mwc-button>`
: ""}
</div>
`
: ""}
@@ -161,6 +170,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
<div class="row">
<ha-switch
.checked=${!this._disabledBy}
.disabled=${this._device?.disabled_by}
@change=${this._disabledByChanged}
>
</ha-switch>

View File

@@ -189,9 +189,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
? (name, entity: any) =>
html`
${name}<br />
${entity.entity_id} |
${this.hass.localize(`component.${entity.platform}.title`) ||
entity.platform}
<div class="secondary">
${entity.entity_id} |
${this.hass.localize(`component.${entity.platform}.title`) ||
entity.platform}
</div>
`
: undefined,
},

View File

@@ -5,6 +5,8 @@ import { classMap } from "lit-html/directives/class-map";
export class HaConfigSection extends LitElement {
@property() public isWide = false;
@property({ type: Boolean }) public vertical = false;
protected render() {
return html`
<div
@@ -16,8 +18,8 @@ export class HaConfigSection extends LitElement {
<div
class="together layout ${classMap({
narrow: !this.isWide,
vertical: !this.isWide,
horizontal: this.isWide,
vertical: this.vertical || !this.isWide,
horizontal: !this.vertical && this.isWide,
})}"
>
<div class="intro"><slot name="introduction"></slot></div>

View File

@@ -68,6 +68,8 @@ class DialogPersonDetail extends LitElement {
@internalProperty() private _submitting = false;
@internalProperty() private _personExists = false;
private _deviceTrackersAvailable = memoizeOne((hass) => {
return Object.keys(hass.states).some(
(entityId) =>
@@ -79,6 +81,7 @@ class DialogPersonDetail extends LitElement {
this._params = params;
this._error = undefined;
if (this._params.entry) {
this._personExists = true;
this._name = this._params.entry.name || "";
this._userId = this._params.entry.user_id || undefined;
this._deviceTrackers = this._params.entry.device_trackers || [];
@@ -88,6 +91,7 @@ class DialogPersonDetail extends LitElement {
: undefined;
this._isAdmin = this._user?.group_ids.includes(SYSTEM_GROUP_ID_ADMIN);
} else {
this._personExists = false;
this._name = "";
this._userId = undefined;
this._user = undefined;
@@ -398,6 +402,7 @@ class DialogPersonDetail extends LitElement {
await this._params!.updateEntry(values);
} else {
await this._params!.createEntry(values);
this._personExists = true;
}
this._params = undefined;
} catch (err) {
@@ -422,6 +427,14 @@ class DialogPersonDetail extends LitElement {
}
private _close(): void {
// If we do not have a person ID yet (= person creation dialog was just cancelled), but
// we already created a user ID for it, delete it now to not have it "free floating".
if (!this._personExists && this._userId) {
deleteUser(this.hass, this._userId);
this._params?.refreshUsers();
this._userId = undefined;
}
this._params = undefined;
}

View File

@@ -241,7 +241,7 @@ export class DialogAddUser extends LitElement {
user = userResponse.user;
} catch (err) {
this._loading = false;
this._error = err.code;
this._error = err.message;
return;
}
@@ -255,7 +255,7 @@ export class DialogAddUser extends LitElement {
} catch (err) {
await deleteUser(this.hass, user.id);
this._loading = false;
this._error = err.code;
this._error = err.message;
return;
}

View File

@@ -13,6 +13,7 @@ import {
} from "lit-element";
import { computeRTLDirection } from "../../../common/util/compute_rtl";
import { createCloseHeading } from "../../../components/ha-dialog";
import "../../../components/ha-help-tooltip";
import "../../../components/ha-formfield";
import "../../../components/ha-switch";
import { adminChangePassword } from "../../../data/auth";
@@ -37,6 +38,8 @@ class DialogUserDetail extends LitElement {
@internalProperty() private _isAdmin?: boolean;
@internalProperty() private _isActive?: boolean;
@internalProperty() private _error?: string;
@internalProperty() private _params?: UserDetailDialogParams;
@@ -48,6 +51,7 @@ class DialogUserDetail extends LitElement {
this._error = undefined;
this._name = params.entry.name || "";
this._isAdmin = params.entry.group_ids.includes(SYSTEM_GROUP_ID_ADMIN);
this._isActive = params.entry.is_active;
await this.updateComplete;
}
@@ -91,15 +95,6 @@ class DialogUserDetail extends LitElement {
</span>
`
: ""}
${user.is_active
? html`
<span class="state"
>${this.hass.localize(
"ui.panel.config.users.editor.active"
)}</span
>
`
: ""}
</div>
<div class="form">
<paper-input
@@ -110,17 +105,21 @@ class DialogUserDetail extends LitElement {
"ui.panel.config.users.editor.name"
)}"
></paper-input>
<ha-formfield
.label=${this.hass.localize("ui.panel.config.users.editor.admin")}
.dir=${computeRTLDirection(this.hass)}
>
<ha-switch
.disabled=${user.system_generated || user.is_owner}
.checked=${this._isAdmin}
@change=${this._adminChanged}
<div class="row">
<ha-formfield
.label=${this.hass.localize(
"ui.panel.config.users.editor.admin"
)}
.dir=${computeRTLDirection(this.hass)}
>
</ha-switch>
</ha-formfield>
<ha-switch
.disabled=${user.system_generated || user.is_owner}
.checked=${this._isAdmin}
@change=${this._adminChanged}
>
</ha-switch>
</ha-formfield>
</div>
${!this._isAdmin
? html`
<br />
@@ -129,6 +128,27 @@ class DialogUserDetail extends LitElement {
)}
`
: ""}
<div class="row">
<ha-formfield
.label=${this.hass.localize(
"ui.panel.config.users.editor.active"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-switch
.disabled=${user.system_generated || user.is_owner}
.checked=${this._isActive}
@change=${this._activeChanged}
>
</ha-switch>
</ha-formfield>
<ha-help-tooltip
.label=${this.hass.localize(
"ui.panel.config.users.editor.active_tooltip"
)}
>
</ha-help-tooltip>
</div>
</div>
</div>
@@ -192,11 +212,16 @@ class DialogUserDetail extends LitElement {
this._isAdmin = ev.target.checked;
}
private async _activeChanged(ev): Promise<void> {
this._isActive = ev.target.checked;
}
private async _updateEntry() {
this._submitting = true;
try {
await this._params!.updateEntry({
name: this._name.trim(),
is_active: this._isActive,
group_ids: [
this._isAdmin ? SYSTEM_GROUP_ID_ADMIN : SYSTEM_GROUP_ID_USER,
],
@@ -293,8 +318,13 @@ class DialogUserDetail extends LitElement {
.state:not(:first-child) {
margin-left: 8px;
}
ha-switch {
margin-top: 8px;
.row {
display: flex;
padding: 8px 0;
}
ha-help-tooltip {
margin-left: 4px;
position: relative;
}
`,
];

View File

@@ -46,10 +46,17 @@ export class HaConfigUsers extends LitElement {
width: "25%",
direction: "asc",
grows: true,
template: (name) => html`
${name ||
this.hass!.localize("ui.panel.config.users.editor.unnamed_user")}
`,
template: (name, user: any) =>
narrow
? html` ${name}<br />
<div class="secondary">
${user.username} |
${this.hass.localize(`groups.${user.group_ids[0]}`)}
</div>`
: html` ${name ||
this.hass!.localize(
"ui.panel.config.users.editor.unnamed_user"
)}`,
},
username: {
title: this.hass.localize(
@@ -59,6 +66,7 @@ export class HaConfigUsers extends LitElement {
filterable: true,
width: "20%",
direction: "asc",
hidden: narrow,
template: (username) => html`
${username ||
this.hass!.localize("ui.panel.config.users.editor.unnamed_user")}
@@ -71,13 +79,24 @@ export class HaConfigUsers extends LitElement {
sortable: true,
filterable: true,
width: "20%",
direction: "asc",
hidden: narrow,
template: (groupIds) => html`
${this.hass.localize(`groups.${groupIds[0]}`)}
`,
},
};
if (!narrow) {
columns.system_generated = {
is_active: {
title: this.hass.localize(
"ui.panel.config.users.picker.headers.is_active"
),
type: "icon",
sortable: true,
filterable: true,
width: "80px",
template: (is_active) =>
is_active ? html`<ha-icon icon="hass:check"> </ha-icon>` : "",
},
system_generated: {
title: this.hass.localize(
"ui.panel.config.users.picker.headers.system"
),
@@ -87,8 +106,9 @@ export class HaConfigUsers extends LitElement {
width: "160px",
template: (generated) =>
generated ? html`<ha-icon icon="hass:check"> </ha-icon>` : "",
};
}
},
};
return columns;
}
);

View File

@@ -84,9 +84,6 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
}
public setConfig(config: ButtonCardConfig): void {
if (!config.entity) {
throw new Error("Entity must be specified");
}
if (config.entity && !isValidEntityId(config.entity)) {
throw new Error("Invalid entity");
}

View File

@@ -109,7 +109,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
}
public setConfig(config: EntitiesCardConfig): void {
if (!config || !config.entities.length) {
if (!config.entities || !Array.isArray(config.entities)) {
throw new Error("Entities must be specified");
}

View File

@@ -2,7 +2,14 @@ import { customElement } from "lit-element";
import { HuiButtonCard } from "./hui-button-card";
@customElement("hui-entity-button-card")
class HuiEntityButtonCard extends HuiButtonCard {}
class HuiEntityButtonCard extends HuiButtonCard {
public setConfig(config): void {
if (!config.entity) {
throw new Error("Entity must be specified");
}
super.setConfig(config);
}
}
declare global {
interface HTMLElementTagNameMap {

View File

@@ -16,7 +16,6 @@ import "../../../components/state-history-charts";
import { CacheConfig, getRecentWithCache } from "../../../data/cached-history";
import { HistoryResult } from "../../../data/history";
import { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entites";
import { hasConfigOrEntitiesChanged } from "../common/has-changed";
import { processConfigEntities } from "../common/process-config-entities";
import { EntityConfig } from "../entity-rows/types";
@@ -30,22 +29,9 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
return document.createElement("hui-history-graph-card-editor");
}
public static getStubConfig(
hass: HomeAssistant,
entities: string[],
entitiesFallback: string[]
): HistoryGraphCardConfig {
const includeDomains = ["sensor"];
const maxEntities = 1;
const foundEntities = findEntities(
hass,
maxEntities,
entities,
entitiesFallback,
includeDomains
);
return { type: "history-graph", entities: foundEntities };
public static getStubConfig(): HistoryGraphCardConfig {
// Hard coded to sun.sun to prevent high server load when it would pick an entity with a lot of state changes
return { type: "history-graph", entities: ["sun.sun"] };
}
@property({ attribute: false }) public hass?: HomeAssistant;
@@ -71,12 +57,12 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
}
public setConfig(config: HistoryGraphCardConfig): void {
if (!config.entities.length) {
throw new Error("Entities must be specified");
if (!config.entities || !Array.isArray(config.entities)) {
throw new Error("Entities need to be an array");
}
if (config.entities && !Array.isArray(config.entities)) {
throw new Error("Entities need to be an array");
if (!config.entities.length) {
throw new Error("You must include at least one entity");
}
this._config = config;

View File

@@ -29,7 +29,7 @@ class HuiHorizontalStackCard extends HuiStackCard {
}
#root > * {
flex: 1 1 0;
margin: 0 4px;
margin: var(--horizontal-stack-card-margin, var(--stack-card-margin, 0 4px));
min-width: 0;
}
#root > *:first-child {

View File

@@ -246,78 +246,73 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
${!isUnavailable &&
(mediaDescription || stateObj.attributes.media_title || showControls)
? html`
<div
class="title-controls"
style=${styleMap({
paddingRight: isOffState
? "0"
: `${this._cardHeight - 40}px`,
})}
>
${!mediaDescription && !stateObj.attributes.media_title
? ""
: html`
<div class="media-info">
<hui-marquee
.text=${stateObj.attributes.media_title ||
mediaDescription}
.active=${this._marqueeActive}
@mouseover=${this._marqueeMouseOver}
@mouseleave=${this._marqueeMouseLeave}
></hui-marquee>
${!stateObj.attributes.media_title
? ""
: mediaDescription}
</div>
`}
${!showControls
? ""
: html`
<div class="controls">
${controls!.map(
(control) => html`
<ha-icon-button
.title=${this.hass.localize(
`ui.card.media_player.${control.action}`
)}
.icon=${control.icon}
action=${control.action}
@click=${this._handleClick}
></ha-icon-button>
`
)}
${supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA)
? html`
<mwc-icon-button
class="browse-media"
<div>
<div class="title-controls">
${!mediaDescription && !stateObj.attributes.media_title
? ""
: html`
<div class="media-info">
<hui-marquee
.text=${stateObj.attributes.media_title ||
mediaDescription}
.active=${this._marqueeActive}
@mouseover=${this._marqueeMouseOver}
@mouseleave=${this._marqueeMouseLeave}
></hui-marquee>
${!stateObj.attributes.media_title
? ""
: mediaDescription}
</div>
`}
${!showControls
? ""
: html`
<div class="controls">
${controls!.map(
(control) => html`
<ha-icon-button
.title=${this.hass.localize(
"ui.card.media_player.browse_media"
`ui.card.media_player.${control.action}`
)}
@click=${this._handleBrowseMedia}
><ha-svg-icon
.path=${mdiPlayBoxMultiple}
></ha-svg-icon
></mwc-icon-button>
.icon=${control.icon}
action=${control.action}
@click=${this._handleClick}
></ha-icon-button>
`
: ""}
</div>
)}
${supportsFeature(stateObj, SUPPORT_BROWSE_MEDIA)
? html`
<mwc-icon-button
class="browse-media"
.title=${this.hass.localize(
"ui.card.media_player.browse_media"
)}
@click=${this._handleBrowseMedia}
><ha-svg-icon
.path=${mdiPlayBoxMultiple}
></ha-svg-icon
></mwc-icon-button>
`
: ""}
</div>
`}
</div>
${!this._showProgressBar
? ""
: html`
<paper-progress
.max=${stateObj.attributes.media_duration}
style=${styleMap({
"--paper-progress-active-color":
this._foregroundColor || "var(--accent-color)",
cursor: supportsFeature(stateObj, SUPPORT_SEEK)
? "pointer"
: "initial",
})}
@click=${this._handleSeek}
></paper-progress>
`}
</div>
${!this._showProgressBar
? ""
: html`
<paper-progress
.max=${stateObj.attributes.media_duration}
style=${styleMap({
"--paper-progress-active-color":
this._foregroundColor || "var(--accent-color)",
cursor: supportsFeature(stateObj, SUPPORT_SEEK)
? "pointer"
: "initial",
})}
@click=${this._handleSeek}
></paper-progress>
`}
`
: ""}
</div>
@@ -635,6 +630,11 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
.player {
position: relative;
padding: 16px;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
color: var(--text-primary-color);
transition-property: color, padding;
transition-duration: 0.4s;
@@ -671,7 +671,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
mwc-icon-button.browse-media {
position: absolute;
right: 0;
right: 4px;
--mdc-icon-size: 24px;
}
@@ -693,7 +693,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
.more-info {
position: absolute;
top: 4px;
right: 0px;
right: 4px;
}
.media-info {

View File

@@ -29,7 +29,7 @@ class HuiVerticalStackCard extends HuiStackCard {
height: 100%;
}
#root > * {
margin: 4px 0 4px 0;
margin: var(--vertical-stack-card-margin, var(--stack-card-margin, 4px 0));
}
#root > *:first-child {
margin-top: 0;

View File

@@ -1,7 +1,8 @@
import "@material/mwc-button";
import "@material/mwc-list/mwc-list-item";
import "@material/mwc-icon-button";
import "../../../components/ha-button-menu";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import "@material/mwc-list/mwc-list-item";
import { mdiArrowDown, mdiArrowUp, mdiDotsVertical } from "@mdi/js";
import {
css,
CSSResult,
@@ -9,21 +10,20 @@ import {
html,
LitElement,
property,
TemplateResult,
queryAssignedNodes,
TemplateResult,
} from "lit-element";
import { HomeAssistant } from "../../../types";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { swapCard, moveCard, addCard, deleteCard } from "../editor/config-util";
import { confDeleteCard } from "../editor/delete-card";
import { Lovelace, LovelaceCard } from "../types";
import { computeCardSize } from "../common/compute-card-size";
import { mdiDotsVertical, mdiArrowDown, mdiArrowUp } from "@mdi/js";
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
import { showSelectViewDialog } from "../editor/select-view/show-select-view-dialog";
import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-button-menu";
import { saveConfig } from "../../../data/lovelace";
import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box";
import { HomeAssistant } from "../../../types";
import { showSaveSuccessToast } from "../../../util/toast-saved-success";
import { computeCardSize } from "../common/compute-card-size";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { addCard, deleteCard, moveCard, swapCard } from "../editor/config-util";
import { showSelectViewDialog } from "../editor/select-view/show-select-view-dialog";
import { Lovelace, LovelaceCard } from "../types";
@customElement("hui-card-options")
export class HuiCardOptions extends LitElement {
@@ -168,11 +168,7 @@ export class HuiCardOptions extends LitElement {
}
private _editCard(): void {
showEditCardDialog(this, {
lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig,
path: this.path!,
});
fireEvent(this, "ll-edit-card", { path: this.path! });
}
private _cardUp(): void {
@@ -229,7 +225,7 @@ export class HuiCardOptions extends LitElement {
}
private _deleteCard(): void {
confDeleteCard(this, this.hass!, this.lovelace!, this.path!);
fireEvent(this, "ll-delete-card", { path: this.path! });
}
}

View File

@@ -72,7 +72,7 @@ class HuiMarquee extends LitElement {
display: flex;
position: relative;
align-items: center;
height: 1em;
height: 1.2em;
contain: strict;
}

View File

@@ -59,6 +59,9 @@ export class HuiThemeSelectEditor extends LitElement {
paper-dropdown-menu {
width: 100%;
}
paper-item {
cursor: pointer;
}
`;
}

View File

@@ -353,11 +353,9 @@ export class HuiCardPicker extends LitElement {
max-width: 500px;
display: flex;
flex-direction: column;
border-radius: 4px;
border: 1px solid var(--divider-color);
border-radius: var(--ha-card-border-radius, 4px);
background: var(--primary-background-color, #fafafa);
cursor: pointer;
box-sizing: border-box;
position: relative;
}
@@ -375,7 +373,6 @@ export class HuiCardPicker extends LitElement {
--ha-card-background,
var(--card-background-color, white)
);
border-radius: 0 0 4px 4px;
border-bottom: 1px solid var(--divider-color);
}
@@ -408,6 +405,10 @@ export class HuiCardPicker extends LitElement {
width: 100%;
height: 100%;
z-index: 1;
box-sizing: border-box;
border: var(--ha-card-border-width, 1px) solid
var(--ha-card-border-color, var(--divider-color));
border-radius: var(--ha-card-border-radius, 4px);
}
.manual {

View File

@@ -450,6 +450,10 @@ export class HuiDialogEditCard extends LitElement
}
.element-preview {
position: relative;
height: max-content;
background: var(--primary-background-color);
padding: 4px;
border-radius: 4px;
}
.element-preview ha-circular-progress {
top: 50%;

View File

@@ -8,7 +8,7 @@ export interface CreateCardDialogParams {
entities?: string[]; // We can pass entity id's that will be added to the config when a card is picked
}
const importCreateCardDialog = () => import("./hui-dialog-create-card");
export const importCreateCardDialog = () => import("./hui-dialog-create-card");
export const showCreateCardDialog = (
element: HTMLElement,

View File

@@ -6,7 +6,7 @@ export interface DeleteCardDialogParams {
cardConfig?: LovelaceCardConfig;
}
const importDeleteCardDialog = () => import("./hui-dialog-delete-card");
export const importDeleteCardDialog = () => import("./hui-dialog-delete-card");
export const showDeleteCardDialog = (
element: HTMLElement,

View File

@@ -8,7 +8,7 @@ export interface EditCardDialogParams {
cardConfig?: LovelaceCardConfig;
}
const importEditCardDialog = () => import("./hui-dialog-edit-card");
export const importEditCardDialog = () => import("./hui-dialog-edit-card");
export const showEditCardDialog = (
element: HTMLElement,

View File

@@ -793,10 +793,6 @@ class HUIRoot extends LitElement {
ha-app-layout {
min-height: 100%;
background: var(
--lovelace-background,
var(--primary-background-color)
);
}
ha-tabs {
width: 100%;
@@ -884,6 +880,12 @@ class HUIRoot extends LitElement {
.menu-link {
text-decoration: none;
}
hui-view {
background: var(
--lovelace-background,
var(--primary-background-color)
);
}
`,
];
}

View File

@@ -1,3 +1,10 @@
// hui-view dependencies for when in edit mode.
import "../../../components/ha-fab";
import "../components/hui-card-options";
import { importCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
import { importDeleteCardDialog } from "../editor/card-editor/show-delete-card-dialog";
import { importEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
importCreateCardDialog();
importDeleteCardDialog();
importEditCardDialog();

View File

@@ -10,6 +10,7 @@ import {
TemplateResult,
} from "lit-element";
import { classMap } from "lit-html/directives/class-map";
import { fireEvent } from "../../../common/dom/fire_event";
import { computeRTL } from "../../../common/util/compute_rtl";
import { nextRender } from "../../../common/util/render-status";
import "../../../components/entity/ha-state-label-badge";
@@ -21,7 +22,6 @@ import type {
import type { HomeAssistant } from "../../../types";
import type { HuiErrorCard } from "../cards/hui-error-card";
import { computeCardSize } from "../common/compute-card-size";
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
let editCodeLoaded = false;
@@ -148,11 +148,7 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
}
private _addCard(): void {
showCreateCardDialog(this, {
lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig,
path: [this.index!],
});
fireEvent(this, "ll-create-card");
}
private async _createColumns() {
@@ -293,7 +289,7 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
.column > * {
display: block;
margin: 4px 4px 8px;
margin: var(--masonry-view-card-margin, 4px 4px 8px);
}
ha-fab {

View File

@@ -20,11 +20,23 @@ import { processConfigEntities } from "../common/process-config-entities";
import { createBadgeElement } from "../create-element/create-badge-element";
import { createCardElement } from "../create-element/create-card-element";
import { createViewElement } from "../create-element/create-view-element";
import { showCreateCardDialog } from "../editor/card-editor/show-create-card-dialog";
import { showEditCardDialog } from "../editor/card-editor/show-edit-card-dialog";
import { confDeleteCard } from "../editor/delete-card";
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
const DEFAULT_VIEW_LAYOUT = "masonry";
const PANEL_VIEW_LAYOUT = "panel";
declare global {
// for fire event
interface HASSDomEvents {
"ll-create-card": undefined;
"ll-edit-card": { path: [number] | [number, number] };
"ll-delete-card": { path: [number] | [number, number] };
}
}
@customElement("hui-view")
export class HUIView extends UpdatingElement {
@property({ attribute: false }) public hass?: HomeAssistant;
@@ -106,6 +118,23 @@ export class HUIView extends UpdatingElement {
if (configChanged && !this._layoutElement) {
this._layoutElement = createViewElement(viewConfig!);
this._layoutElement.addEventListener("ll-create-card", () => {
showCreateCardDialog(this, {
lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig,
path: [this.index!],
});
});
this._layoutElement.addEventListener("ll-edit-card", (ev) => {
showEditCardDialog(this, {
lovelaceConfig: this.lovelace!.config,
saveConfig: this.lovelace!.saveConfig,
path: ev.detail.path,
});
});
this._layoutElement.addEventListener("ll-delete-card", (ev) => {
confDeleteCard(this, this.hass!, this.lovelace!, ev.detail.path);
});
}
if (configChanged) {

View File

@@ -1,154 +0,0 @@
import "@material/mwc-button";
import "@polymer/paper-dialog/paper-dialog";
import "../../components/ha-circular-progress";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../components/ha-card";
import LocalizeMixin from "../../mixins/localize-mixin";
import "../../styles/polymer-ha-style";
/*
* @appliesMixin LocalizeMixin
*/
class HaChangePasswordCard extends LocalizeMixin(PolymerElement) {
static get template() {
return html`
<style include="ha-style">
.error {
color: red;
}
.status {
color: var(--primary-color);
}
.error,
.status {
position: absolute;
top: -4px;
}
.currentPassword {
margin-top: -4px;
}
</style>
<div>
<ha-card
header="[[localize('ui.panel.profile.change_password.header')]]"
>
<div class="card-content">
<template is="dom-if" if="[[_errorMsg]]">
<div class="error">[[_errorMsg]]</div>
</template>
<template is="dom-if" if="[[_statusMsg]]">
<div class="status">[[_statusMsg]]</div>
</template>
<paper-input
class="currentPassword"
label="[[localize('ui.panel.profile.change_password.current_password')]]"
type="password"
value="{{_currentPassword}}"
required
auto-validate
error-message="[[localize('ui.panel.profile.change_password.error_required')]]"
></paper-input>
<template is="dom-if" if="[[_currentPassword]]">
<paper-input
label="[[localize('ui.panel.profile.change_password.new_password')]]"
type="password"
value="{{_password1}}"
required
auto-validate
error-message="[[localize('ui.panel.profile.change_password.error_required')]]"
></paper-input>
<paper-input
label="[[localize('ui.panel.profile.change_password.confirm_new_password')]]"
type="password"
value="{{_password2}}"
required
auto-validate
error-message="[[localize('ui.panel.profile.change_password.error_required')]]"
></paper-input>
</template>
</div>
<div class="card-actions">
<template is="dom-if" if="[[_loading]]">
<div><ha-circular-progress active></ha-circular-progress></div>
</template>
<template is="dom-if" if="[[!_loading]]">
<mwc-button on-click="_changePassword"
>[[localize('ui.panel.profile.change_password.submit')]]</mwc-button
>
</template>
</div>
</ha-card>
</div>
`;
}
static get properties() {
return {
hass: Object,
_loading: {
type: Boolean,
value: false,
},
// Error message when can't talk to server etc
_statusMsg: String,
_errorMsg: String,
_currentPassword: String,
_password1: String,
_password2: String,
};
}
ready() {
super.ready();
this.addEventListener("keypress", (ev) => {
this._statusMsg = null;
if (ev.keyCode === 13) {
this._changePassword();
}
});
}
async _changePassword() {
this._statusMsg = null;
if (!this._currentPassword || !this._password1 || !this._password2) return;
if (this._password1 !== this._password2) {
this._errorMsg = "New password confirmation doesn't match";
return;
}
if (this._currentPassword === this._password1) {
this._errorMsg = "New password must be different than current password";
return;
}
this._loading = true;
this._errorMsg = null;
try {
await this.hass.callWS({
type: "config/auth_provider/homeassistant/change_password",
current_password: this._currentPassword,
new_password: this._password1,
});
this.setProperties({
_statusMsg: "Password changed successfully",
_currentPassword: null,
_password1: null,
_password2: null,
});
} catch (err) {
this._errorMsg = err.message;
}
this._loading = false;
}
}
customElements.define("ha-change-password-card", HaChangePasswordCard);

View File

@@ -0,0 +1,195 @@
import "@polymer/paper-input/paper-input";
import "@polymer/paper-dialog/paper-dialog";
import {
css,
CSSResult,
customElement,
html,
internalProperty,
LitElement,
property,
PropertyValues,
TemplateResult,
} from "lit-element";
import "@material/mwc-button";
import "../../components/ha-circular-progress";
import "../../components/ha-card";
import { haStyle } from "../../resources/styles";
import type { HomeAssistant } from "../../types";
@customElement("ha-change-password-card")
class HaChangePasswordCard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@internalProperty() private _loading = false;
@internalProperty() private _statusMsg?: string;
@internalProperty() private _errorMsg?: string;
@internalProperty() private _currentPassword?: string;
@internalProperty() private _password?: string;
@internalProperty() private _passwordConfirm?: string;
protected render(): TemplateResult {
return html`
<div>
<ha-card
.header=${this.hass.localize(
"ui.panel.profile.change_password.header"
)}
>
<div class="card-content">
${this._errorMsg
? html` <div class="error">${this._errorMsg}</div> `
: ""}
${this._statusMsg
? html` <div class="status">${this._statusMsg}</div> `
: ""}
<paper-input
id="currentPassword"
.label=${this.hass.localize(
"ui.panel.profile.change_password.current_password"
)}
type="password"
.value=${this._currentPassword}
@value-changed=${this._currentPasswordChanged}
required
></paper-input>
${this._currentPassword
? html` <paper-input
.label=${this.hass.localize(
"ui.panel.profile.change_password.new_password"
)}
name="password"
type="password"
.value=${this._password}
@value-changed=${this._newPasswordChanged}
required
auto-validate
></paper-input>
<paper-input
.label=${this.hass.localize(
"ui.panel.profile.change_password.confirm_new_password"
)}
name="passwordConfirm"
type="password"
.value=${this._passwordConfirm}
@value-changed=${this._newPasswordConfirmChanged}
required
auto-validate
></paper-input>`
: ""}
</div>
<div class="card-actions">
${this._loading
? html`<div>
<ha-circular-progress active></ha-circular-progress>
</div>`
: html`<mwc-button
@click=${this._changePassword}
.disabled=${!this._passwordConfirm}
>${this.hass.localize(
"ui.panel.profile.change_password.submit"
)}</mwc-button
>`}
</div>
</ha-card>
</div>
`;
}
private _currentPasswordChanged(ev: CustomEvent) {
this._currentPassword = ev.detail.value;
}
private _newPasswordChanged(ev: CustomEvent) {
this._password = ev.detail.value;
}
private _newPasswordConfirmChanged(ev: CustomEvent) {
this._passwordConfirm = ev.detail.value;
}
protected firstUpdated(changedProps: PropertyValues) {
super.firstUpdated(changedProps);
this.addEventListener("keypress", (ev) => {
this._statusMsg = undefined;
if (ev.keyCode === 13) {
this._changePassword();
}
});
}
private async _changePassword() {
this._statusMsg = undefined;
if (!this._currentPassword || !this._password || !this._passwordConfirm) {
return;
}
if (this._password !== this._passwordConfirm) {
this._errorMsg = this.hass.localize(
"ui.panel.profile.change_password.error_new_mismatch"
);
return;
}
if (this._currentPassword === this._password) {
this._errorMsg = this.hass.localize(
"ui.panel.profile.change_password.error_new_is_old"
);
return;
}
this._loading = true;
this._errorMsg = undefined;
try {
await this.hass.callWS({
type: "config/auth_provider/homeassistant/change_password",
current_password: this._currentPassword,
new_password: this._password,
});
} catch (err) {
this._errorMsg = err.message;
return;
} finally {
this._loading = false;
}
this._statusMsg = this.hass.localize(
"ui.panel.profile.change_password.success"
);
this._currentPassword = undefined;
this._password = undefined;
this._passwordConfirm = undefined;
}
static get styles(): CSSResult[] {
return [
haStyle,
css`
.error {
color: var(--error-color);
}
.status {
color: var(--primary-color);
}
#currentPassword {
margin-top: -8px;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-change-password-card": HaChangePasswordCard;
}
}

View File

@@ -25,7 +25,7 @@ class HaPushNotificationsRow extends LocalizeMixin(PolymerElement) {
>[[localize('ui.panel.profile.push_notifications.header')]]</span
>
<span slot="description">
[[_description(_platformLoaded, _pushSupported)]]
[[localize(_descrLocalizeKey)]]
<a
href="[[_computeDocumentationUrl(hass)]]"
target="_blank"
@@ -45,6 +45,10 @@ class HaPushNotificationsRow extends LocalizeMixin(PolymerElement) {
return {
hass: Object,
narrow: Boolean,
_descrLocalizeKey: {
type: String,
computed: "_descriptionKey(_platformLoaded, _pushSupported)",
},
_platformLoaded: {
type: Boolean,
computed: "_compPlatformLoaded(hass)",
@@ -72,7 +76,7 @@ class HaPushNotificationsRow extends LocalizeMixin(PolymerElement) {
return !platformLoaded || !pushSupported_;
}
_description(platformLoaded, pushSupported_) {
_descriptionKey(platformLoaded, pushSupported_) {
let key;
if (!pushSupported_) {
key = "error_use_https";
@@ -81,7 +85,7 @@ class HaPushNotificationsRow extends LocalizeMixin(PolymerElement) {
} else {
key = "description";
}
return this.localize(`ui.panel.profile.push_notifications.${key}`);
return `ui.panel.profile.push_notifications.${key}`;
}
}

View File

@@ -21,7 +21,8 @@ export const panelTitleMixin = <T extends Constructor<HassBaseEl>>(
if (
!oldHass ||
oldHass.panels !== this.hass.panels ||
oldHass.panelUrl !== this.hass.panelUrl
oldHass.panelUrl !== this.hass.panelUrl ||
oldHass.localize !== this.hass.localize
) {
setTitle(getPanelTitle(this.hass));
}

View File

@@ -36,6 +36,8 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
// eslint-disable-next-line: variable-name
private __coreProgress?: string;
private __loadedFragmetTranslations: Set<string> = new Set();
private __loadedTranslations: {
// track what things have been loaded
[category: string]: LoadedTranslationCategory;
@@ -101,6 +103,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
document.querySelector("html")!.setAttribute("lang", hass.language);
this.style.direction = computeRTL(hass) ? "rtl" : "ltr";
this._loadCoreTranslations(hass.language);
this.__loadedFragmetTranslations = new Set();
this._loadFragmentTranslations(hass.language, hass.panelUrl);
}
@@ -195,10 +198,31 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
language: string,
panelUrl: string
) {
if (translationMetadata.fragments.includes(panelUrl)) {
const result = await getTranslation(panelUrl, language);
this._updateResources(result.language, result.data);
if (!panelUrl) {
return;
}
const panelComponent = this.hass?.panels?.[panelUrl]?.component_name;
// If it's the first call we don't have panel info yet to check the component.
// If the url is not known it might be a custom lovelace dashboard, so we load lovelace translations
const fragment = translationMetadata.fragments.includes(
panelComponent || panelUrl
)
? panelComponent || panelUrl
: !panelComponent
? "lovelace"
: undefined;
if (!fragment) {
return;
}
if (this.__loadedFragmetTranslations.has(fragment)) {
return;
}
this.__loadedFragmetTranslations.add(fragment);
const result = await getTranslation(fragment, language);
this._updateResources(result.language, result.data);
}
private async _loadCoreTranslations(language: string) {
@@ -210,7 +234,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
this.__coreProgress = language;
try {
const result = await getTranslation(null, language);
this._updateResources(result.language, result.data);
await this._updateResources(result.language, result.data);
} finally {
this.__coreProgress = undefined;
}
@@ -226,18 +250,29 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
// before this.hass is even created. In this case our base state comes
// from this._pendingHass instead. Otherwise the first set of strings is
// overwritten when we call _updateHass the second time!
const baseHass = this.hass ?? this._pendingHass;
// Allow hass to be updated
await new Promise((resolve) => setTimeout(resolve, 0));
if (language !== (this.hass ?? this._pendingHass).language) {
// the language was changed, abort
return;
}
const resources = {
[language]: {
...baseHass?.resources?.[language],
...(this.hass ?? this._pendingHass)?.resources?.[language],
...data,
},
};
const changes: Partial<HomeAssistant> = { resources };
if (this.hass && language === this.hass.language) {
changes.localize = await computeLocalize(this, language, resources);
const changes: Partial<HomeAssistant> = {
resources,
localize: await computeLocalize(this, language, resources),
};
if (language === (this.hass ?? this._pendingHass).language) {
this._updateHass(changes);
}
this._updateHass(changes);
}
private _refetchCachedHassTranslations(

View File

@@ -98,7 +98,8 @@
"disabled_by": {
"user": "User",
"integration": "Integration",
"config_entry": "Config Entry"
"config_entry": "Config Entry",
"device": "Device"
}
},
"ui": {
@@ -327,6 +328,7 @@
"entity-picker": {
"entity": "Entity",
"clear": "Clear",
"no_match": "No matching entities found",
"show_entities": "Show entities"
},
"entity-attribute-picker": {
@@ -334,6 +336,16 @@
"show_attributes": "Show attributes"
}
},
"target-picker": {
"expand_area_id": "Expand this area in the seperate devices and entities that it contains. After expanding it will not update the devices and entities when the area changes.",
"expand_device_id": "Expand this device in seperate entities. After expanding it will not update the entities when the device changes.",
"remove_area_id": "Remove area",
"remove_device_id": "Remove device",
"remove_entity_id": "Remove entity",
"add_area_id": "Pick area",
"add_device_id": "Pick device",
"add_entity_id": "Pick entity"
},
"user-picker": {
"no_user": "No user",
"add_user": "Add user",
@@ -348,6 +360,8 @@
"clear": "Clear",
"toggle": "Toggle",
"show_devices": "Show devices",
"no_devices": "You don't have any devices",
"no_match": "No matching devices found",
"device": "Device",
"no_area": "No area"
},
@@ -356,6 +370,8 @@
"show_areas": "Show areas",
"area": "Area",
"add_new": "Add new area…",
"no_areas": "You don't have any areas",
"no_match": "No matching areas found",
"add_dialog": {
"title": "Add new area",
"text": "Enter the name of the new area.",
@@ -612,6 +628,8 @@
"unavailable": "This entity is not currently available.",
"enabled_label": "Enable entity",
"enabled_cause": "Disabled by {cause}.",
"device_disabled": "The device of this entity is disabled.",
"open_device_settings": "Open device settings",
"enabled_description": "Disabled entities will not be added to Home Assistant.",
"enabled_delay_confirm": "The enabled entities will be added to Home Assistant in {delay} seconds",
"enabled_restart_confirm": "Restart Home Assistant to finish enabling the entities",
@@ -787,7 +805,7 @@
},
"areas": {
"caption": "Areas",
"description": "Manage areas in your home",
"description": "Group devices and entities into areas",
"data_table": {
"area": "Area",
"devices": "Devices"
@@ -817,7 +835,7 @@
},
"tags": {
"caption": "Tags",
"description": "Manage tags",
"description": "Trigger automations when a NFC tag, QR code, etc. is scanned",
"learn_more": "Learn more about tags",
"no_tags": "No tags",
"add_tag": "Add tag",
@@ -848,7 +866,7 @@
},
"helpers": {
"caption": "Helpers",
"description": "Manage elements that help build automations",
"description": "Elements that help build automations",
"types": {
"input_text": "Text",
"input_number": "Number",
@@ -876,7 +894,7 @@
},
"core": {
"caption": "General",
"description": "Change your general Home Assistant configuration",
"description": "Unit system, location, time zone & other general parameters",
"section": {
"core": {
"header": "General Configuration",
@@ -905,7 +923,7 @@
"caption": "Info",
"copy_raw": "Raw Text",
"copy_github": "For GitHub",
"description": "View info about your Home Assistant installation",
"description": "Version, system health and links to documentation",
"home_assistant_logo": "Home Assistant logo",
"path_configuration": "Path to configuration.yaml: {path}",
"developed_by": "Developed by a bunch of awesome people.",
@@ -940,7 +958,7 @@
},
"lovelace": {
"caption": "Lovelace Dashboards",
"description": "Manage your Lovelace Dashboards",
"description": "Create customized sets of cards to control your home",
"dashboards": {
"default_dashboard": "This is the default dashboard",
"caption": "Dashboards",
@@ -1095,7 +1113,7 @@
},
"automation": {
"caption": "Automations",
"description": "Manage automations",
"description": "Create custom behavior rules for your home",
"picker": {
"header": "Automation Editor",
"introduction": "The automation editor allows you to create and edit automations. Please follow the link below to read the instructions to make sure that you have configured Home Assistant correctly.",
@@ -1147,8 +1165,6 @@
"header": "Blueprint",
"blueprint_to_use": "Blueprint to use",
"no_blueprints": "You don't have any blueprints",
"manage_blueprints": "Manage Blueprints",
"inputs": "Inputs",
"no_inputs": "This blueprint doesn't have any inputs."
},
"modes": {
@@ -1445,8 +1461,8 @@
"description": "Manage blueprints",
"overview": {
"header": "Blueprint Editor",
"introduction": "The blueprint editor allows you to create and edit blueprints.",
"learn_more": "Learn more about blueprints",
"introduction": "The blueprint configuration allows you to import and manage your blueprints.",
"learn_more": "Learn more about using blueprints",
"headers": {
"name": "Name",
"domain": "Domain",
@@ -1459,23 +1475,23 @@
"delete_blueprint": "Delete blueprint"
},
"add": {
"header": "Add new blueprint",
"import_header": "Import \"{name}\" (type: {domain})",
"header": "Import a blueprint",
"import_header": "Blueprint \"{name}\"",
"import_introduction": "You can import blueprints of other users from Github and the community forums. Enter the URL of the blueprint below.",
"url": "URL of the blueprint",
"raw_blueprint": "Blueprint content",
"importing": "Importing blueprint...",
"import_btn": "Import blueprint",
"saving": "Saving blueprint...",
"save_btn": "Save blueprint",
"importing": "Loading blueprint...",
"import_btn": "Preview blueprint",
"saving": "Importing blueprint...",
"save_btn": "Import blueprint",
"error_no_url": "Please enter the URL of the blueprint.",
"unsupported_blueprint": "This blueprint is not supported",
"file_name": "Local blueprint file name"
"file_name": "Blueprint Path"
}
},
"script": {
"caption": "Scripts",
"description": "Manage scripts",
"description": "Execute a sequence of actions",
"picker": {
"header": "Script Editor",
"introduction": "The script editor allows you to create and edit scripts. Please follow the link below to read the instructions to make sure that you have configured Home Assistant correctly.",
@@ -1525,7 +1541,7 @@
},
"scene": {
"caption": "Scenes",
"description": "Manage scenes",
"description": "Capture device states and easily recall them later",
"activated": "Activated scene {name}.",
"picker": {
"header": "Scene Editor",
@@ -1571,7 +1587,7 @@
"cloud": {
"description_login": "Logged in as {email}",
"description_not_login": "Not logged in",
"description_features": "Control away from home, integrate with Alexa and Google Assistant.",
"description_features": "Control home when away and integrate with Alexa and Google Assistant",
"login": {
"title": "Cloud Login",
"introduction": "Home Assistant Cloud provides you with a secure remote connection to your instance while away from home. It also allows you to connect with cloud-only services: Amazon Alexa and Google Assistant.",
@@ -1738,18 +1754,27 @@
"devices": {
"add_prompt": "No {name} have been added using this device yet. You can add one by clicking the + button above.",
"caption": "Devices",
"description": "Manage connected devices",
"description": "Manage configured devices",
"device_info": "Device info",
"unnamed_device": "Unnamed device",
"unknown_error": "Unknown error",
"name": "Name",
"update": "Update",
"no_devices": "No devices",
"enabled_label": "Enable device",
"enabled_cause": "The device is disabled by {cause}.",
"disabled_by": {
"user": "User",
"integration": "Integration",
"config_entry": "Config Entry"
},
"enabled_description": "Disabled devices will not be shown and entities belonging to the device will be disabled and not added to Home Assistant.",
"automation": {
"automations": "Automations",
"no_automations": "No automations",
"unknown_automation": "Unknown automation",
"create": "Create automation with device",
"create_disable": "Can't create automation with disabled device",
"triggers": {
"caption": "Do something when...",
"no_triggers": "No triggers",
@@ -1770,12 +1795,14 @@
"script": {
"scripts": "Scripts",
"no_scripts": "No scripts",
"create": "Create script with device"
"create": "Create script with device",
"create_disable": "Can't create script with disabled device"
},
"scene": {
"scenes": "Scenes",
"no_scenes": "No scenes",
"create": "Create scene with device"
"create": "Create scene with device",
"create_disable": "Can't create scene with disabled device"
},
"cant_edit": "You can only edit items that are created in the UI.",
"device_not_found": "Device not found.",
@@ -1790,6 +1817,7 @@
"scenes": "Scenes",
"confirm_rename_entity_ids": "Do you also want to rename the entity IDs of your entities?",
"confirm_rename_entity_ids_warning": "This will not change any configuration (like automations, scripts, scenes, dashboards) that is currently using these entities! You will have to update them yourself to use the new entity IDs!",
"disabled": "Disabled",
"data_table": {
"device": "Device",
"manufacturer": "Manufacturer",
@@ -1801,7 +1829,16 @@
"no_area": "No area"
},
"delete": "Delete",
"confirm_delete": "Are you sure you want to delete this device?"
"confirm_delete": "Are you sure you want to delete this device?",
"picker": {
"search": "Search devices",
"filter": {
"filter": "Filter",
"show_disabled": "Show disabled devices",
"hidden_devices": "{number} hidden {number, plural,\n one {device}\n other {devices}\n}",
"show_all": "Show all"
}
}
},
"entities": {
"caption": "Entities",
@@ -1916,7 +1953,7 @@
},
"integrations": {
"caption": "Integrations",
"description": "Manage integrations",
"description": "Manage integrations with services, devices, ...",
"integration": "integration",
"discovered": "Discovered",
"attention": "Attention required",
@@ -1989,7 +2026,7 @@
},
"users": {
"caption": "Users",
"description": "Manage users",
"description": "Manage the Home Assistant user accounts",
"users_privileges_note": "The user group feature is a work in progress. The user will be unable to administer the instance via the UI. We're still auditing all management API endpoints to ensure that they correctly limit access to administrators.",
"picker": {
"headers": {
@@ -2022,7 +2059,8 @@
"system_generated_users_not_removable": "Unable to remove system generated users.",
"system_generated_users_not_editable": "Unable to update system generated users.",
"unnamed_user": "Unnamed User",
"confirm_user_deletion": "Are you sure you want to delete {name}?"
"confirm_user_deletion": "Are you sure you want to delete {name}?",
"active_tooltip": "Controls if user can login"
},
"add_user": {
"caption": "Add user",
@@ -2871,7 +2909,10 @@
"new_password": "New Password",
"confirm_new_password": "Confirm New Password",
"error_required": "Required",
"submit": "Submit"
"submit": "Submit",
"error_new_mismatch": "Entered new password values do not match",
"error_new_is_old": "New password must be different than current password",
"success": "Password changed successfully"
},
"mfa": {
"header": "Multi-factor Authentication Modules",

View File

@@ -2,6 +2,7 @@
"config_entry": {
"disabled_by": {
"config_entry": "Položka nastavení",
"device": "Zařízení",
"integration": "Integrace",
"user": "Uživatel"
}
@@ -709,6 +710,14 @@
"service-picker": {
"service": "Služba"
},
"target-picker": {
"add_area_id": "Vyberte oblast",
"add_device_id": "Vyberte zařízení",
"add_entity_id": "Vyberte entitu",
"remove_area_id": "Odebrat oblast",
"remove_device_id": "Odebrat zařízení",
"remove_entity_id": "Odebrat entitu"
},
"user-picker": {
"add_user": "Přidat uživatele",
"no_user": "Žádný uživatel",
@@ -732,6 +741,7 @@
"editor": {
"confirm_delete": "Opravdu chcete tuto položku smazat?",
"delete": "Odstranit",
"device_disabled": "Zařízení této entity je zakázáno.",
"enabled_cause": "Zakázáno {cause}.",
"enabled_delay_confirm": "Povolené entity budou přidány do Home Assistant za {delay} sekund",
"enabled_description": "Zakázané entity nebudou přidány do Home Assistant.",
@@ -742,6 +752,7 @@
"icon_error": "Ikony by měly být ve formátu 'prefix:nazevikony', např. 'mdi:home'",
"name": "Jméno",
"note": "Poznámka: U všech integrací to ještě nemusí fungovat.",
"open_device_settings": "Otevřít nastavení zařízení",
"unavailable": "Tato entita není momentálně k dispozici.",
"update": "Aktualizovat"
},
@@ -1028,7 +1039,7 @@
"confirmation_text": "Všechna zařízení v této oblasti budou nastavena jako nepřiřazena.",
"confirmation_title": "Opravdu chcete tuto oblast smazat?"
},
"description": "Správa oblastí ve vaší domácnosti",
"description": "Seskupte zařízení do oblastí",
"editor": {
"area_id": "ID oblasti",
"create": "VYTVOŘIT",
@@ -1050,7 +1061,7 @@
},
"automation": {
"caption": "Automatizace",
"description": "Správa automatizací",
"description": "Vytvořte si pro svůj domov vlastní pravidla chování",
"dialog_new": {
"header": "Vytvoření automatizace",
"how": "Jak chcete vytvořit svou novou automatizaci?",
@@ -1406,7 +1417,8 @@
"file_name": "Název souboru",
"name": "Jméno"
},
"learn_more": "Další informace o šablonkách konfigurace"
"learn_more": "Další informace o šablonkách konfigurace",
"use_blueprint": "Vytvořit automatizaci"
}
},
"cloud": {
@@ -1584,7 +1596,7 @@
},
"core": {
"caption": "Obecné",
"description": "Změny obecného nastavení Home Assistant",
"description": "Jednotkový systém, umístění, časové pásmo a další obecné parametry",
"section": {
"core": {
"core_config": {
@@ -1646,6 +1658,7 @@
"unknown_condition": "Neznámá podmínka"
},
"create": "Vytvořit automatizaci se zařízením",
"create_disable": "Nelze vytvořit automatizaci se zakázaným zařízením",
"no_automations": "Žádné automatizace",
"no_device_automations": "Pro toto zařízení nejsou k dispozici žádné automatizace.",
"triggers": {
@@ -1671,9 +1684,18 @@
"no_devices": "Žádná zařízení"
},
"delete": "Odstranit",
"description": "Správa připojených zařízení",
"description": "Spravujte připojená zařízení",
"device_info": "Informace o zařízení",
"device_not_found": "Zařízení nebylo nalezeno.",
"disabled": "Zakázáno",
"disabled_by": {
"config_entry": "Položka nastavení",
"integration": "Integrace",
"user": "Uživatel"
},
"enabled_cause": "Zařízení je zakázáno přes {cause}.",
"enabled_description": "Zakázaná zařízení se nebudou zobrazovat a entity patřící k těmto zařízením budou zakázány a nebudou přidány do Home Assistant.",
"enabled_label": "Povolit zařízení",
"entities": {
"add_entities_lovelace": "Přidat do Lovelace",
"disabled_entities": "+{count} {count, plural,\n one {zakázaná entita}\n other {zakázaných entit}\n}",
@@ -1683,14 +1705,25 @@
},
"name": "Jméno",
"no_devices": "Žádná zařízení",
"picker": {
"filter": {
"filter": "Filtrovat",
"hidden_devices": "{number} {number, plural,\n one {skryté zařízení}\n few {skrytá zařízení}\n other {skrytých zařízení}\n}",
"show_all": "Zobrazit vše",
"show_disabled": "Zobrazit zakázaná zařízení"
},
"search": "Hledat zařízení"
},
"scene": {
"create": "Vytvořit scénu se zařízením",
"create_disable": "Nelze vytvořit scénu se zakázaným zařízením",
"no_scenes": "Žádné scény",
"scenes": "Scény"
},
"scenes": "Scény",
"script": {
"create": "Vytvořit skript se zařízením",
"create_disable": "Nelze vytvořit skript se zakázaným zařízením",
"no_scripts": "Žádné skripty",
"scripts": "Skripty"
},
@@ -1723,6 +1756,7 @@
},
"header": "Entity",
"headers": {
"area": "Oblast",
"entity_id": "ID entity",
"integration": "Integrace",
"name": "Název",
@@ -1755,7 +1789,7 @@
"header": "Nastavení Home Assistant",
"helpers": {
"caption": "Pomocníci",
"description": "Správa prvků, které mohou pomoci při vytváře automatizací",
"description": "Prvky, které pomáhají vytvářet automatizace",
"dialog": {
"add_helper": "Přidat pomocníka",
"add_platform": "Přidat {platform}",
@@ -1787,7 +1821,7 @@
"copy_github": "Pro GitHub",
"copy_raw": "Nezpracovaný text",
"custom_uis": "Vlastní uživatelská rozhraní:",
"description": "Informace o instalaci Home Assistant",
"description": "Verze, stav systému a odkazy na dokumentaci",
"developed_by": "Vyvinuto partou úžasných lidí.",
"documentation": "Dokumentace",
"frontend": "frontend-ui",
@@ -1893,7 +1927,7 @@
},
"configure": "Nastavit",
"configured": "Nastaveno",
"description": "Správa integrací",
"description": "Spravujte integrace a jejich služby, zařízení, ...",
"details": "Podrobnosti o integraci",
"discovered": "Objeveno",
"home_assistant_website": "stránky Home Assistant",
@@ -1978,7 +2012,7 @@
"open": "Otevřít"
}
},
"description": "Správa Lovelace Dashboardů",
"description": "Vytvořte vlastní sady karet pro ovládání svého domova",
"resources": {
"cant_edit_yaml": "Používáte Lovelace v režimu YAML, proto nemůžete spravovat své zdroje prostřednictvím uživatelského rozhraní. Spravujte je v souboru configuration.yaml.",
"caption": "Zdroje",
@@ -2177,7 +2211,7 @@
"scene": {
"activated": "Aktivovaná scéna {name}.",
"caption": "Scény",
"description": "Správa scén",
"description": "Zachyťte stavy zařízení a snadno je později vyvolejte",
"editor": {
"default_name": "Nová scéna",
"devices": {
@@ -2221,7 +2255,7 @@
},
"script": {
"caption": "Skripty",
"description": "Správa skriptů",
"description": "Provádějte posloupnosti akcí",
"editor": {
"alias": "Název",
"default_name": "Nový skript",
@@ -2332,7 +2366,7 @@
"confirm_remove": "Opravdu chcete odebrat štítek {tag}?",
"confirm_remove_title": "Odebrat štítek?",
"create_automation": "Vytvořit automatizaci se štítkem",
"description": "Správa štítků",
"description": "Spusťte automatizaci skenováním NFC tagu, QR kódu atd.",
"detail": {
"companion_apps": "doprovodné aplikace",
"create": "Vytvořit",
@@ -2371,6 +2405,7 @@
"editor": {
"activate_user": "Aktivovat uživatele",
"active": "Aktivní",
"active_tooltip": "Určuje, zda se uživatel může přihlásit",
"admin": "Administrátor",
"caption": "Zobrazit uživatele",
"change_password": "Změnit heslo",
@@ -2450,6 +2485,16 @@
"value": "Hodnota"
},
"description": "Správa Zigbee Home Automation",
"device_pairing_card": {
"CONFIGURED": "Nastavení dokončeno",
"CONFIGURED_status_text": "Inicializuji",
"INITIALIZED": "Inicializace dokončena",
"INITIALIZED_status_text": "Zařízení je připraveno k použití",
"INTERVIEW_COMPLETE": "Dotazování dokončeno",
"INTERVIEW_COMPLETE_status_text": "Nastavuji",
"PAIRED": "Zařízení nalezeno",
"PAIRED_status_text": "Začínám dotazování"
},
"devices": {
"header": "Zigbee Home Automation - Zařízení"
},
@@ -3379,10 +3424,13 @@
"change_password": {
"confirm_new_password": "Potvrďte nové heslo",
"current_password": "Současné heslo",
"error_new_is_old": "Nové heslo se musí lišit od aktuálního hesla",
"error_new_mismatch": "Zadaná nová hesla se neshodují",
"error_required": "Povinný",
"header": "Změnit heslo",
"new_password": "Nové heslo",
"submit": "Odeslat"
"submit": "Odeslat",
"success": "Heslo bylo úspěšně změněno"
},
"current_user": "Nyní jste přihlášeni jako {fullName}.",
"customize_sidebar": {

View File

@@ -7,6 +7,7 @@
}
},
"groups": {
"owner": "Besitzer",
"system-admin": "Administratoren",
"system-read-only": "Nur-Lesen Benutzer",
"system-users": "Benutzer"
@@ -1740,6 +1741,7 @@
},
"header": "Entitäten",
"headers": {
"area": "Bereich",
"entity_id": "Entitäts-ID",
"integration": "Integration",
"name": "Name",
@@ -2404,14 +2406,18 @@
"system_generated_users_not_editable": "Systemgenerierte Benutzer können nicht aktualisiert werden.",
"system_generated_users_not_removable": "Vom System generierte Benutzer können nicht entfernt werden.",
"unnamed_user": "Unbenannter Benutzer",
"update_user": "Aktualisieren"
"update_user": "Aktualisieren",
"username": "Benutzername"
},
"picker": {
"add_user": "Benutzer hinzufügen",
"headers": {
"group": "Gruppe",
"is_active": "Aktiv",
"is_owner": "Besitzer",
"name": "Name",
"system": "System"
"system": "System",
"username": "Benutzername"
}
},
"users_privileges_note": "Benutzergruppen sind derzeit noch in Entwicklung. Der Benutzer wird nicht in der Lage sein, Änderungen an der Instanz über das UI vorzunehmen. Derzeit überprüfen wir noch alle API Endpunkte um sicherzustellen dass diese nur von Administratoren genutzt werden können."
@@ -2463,6 +2469,15 @@
"value": "Wert"
},
"description": "Zigbee Home Automation Netzwerkmanagement",
"device_pairing_card": {
"CONFIGURED": "Konfiguration abgeschlossen",
"CONFIGURED_status_text": "Initialisieren",
"INITIALIZED": "Initialisierung abgeschlossen",
"INITIALIZED_status_text": "Das Gerät ist einsatzbereit",
"INTERVIEW_COMPLETE": "Interview abgeschlossen",
"INTERVIEW_COMPLETE_status_text": "Konfigurieren",
"PAIRED": "Gerät gefunden"
},
"devices": {
"header": "Zigbee Home Automation - Gerät"
},

View File

@@ -2,6 +2,7 @@
"config_entry": {
"disabled_by": {
"config_entry": "Config Entry",
"device": "Device",
"integration": "Integration",
"user": "User"
}
@@ -710,6 +711,16 @@
"service-picker": {
"service": "Service"
},
"target-picker": {
"add_area_id": "Pick area",
"add_device_id": "Pick device",
"add_entity_id": "Pick entity",
"expand_area_id": "Expand this area in the seperate devices and entities that it contains. After expanding it will not update the devices and entities when the area changes.",
"expand_device_id": "Expand this device in seperate entities. After expanding it will not update the entities when the device changes.",
"remove_area_id": "Remove area",
"remove_device_id": "Remove device",
"remove_entity_id": "Remove entity"
},
"user-picker": {
"add_user": "Add user",
"no_user": "No user",
@@ -733,6 +744,7 @@
"editor": {
"confirm_delete": "Are you sure you want to delete this entry?",
"delete": "Delete",
"device_disabled": "The device of this entity is disabled.",
"enabled_cause": "Disabled by {cause}.",
"enabled_delay_confirm": "The enabled entities will be added to Home Assistant in {delay} seconds",
"enabled_description": "Disabled entities will not be added to Home Assistant.",
@@ -743,6 +755,7 @@
"icon_error": "Icons should be in the format 'prefix:iconname', e.g. 'mdi:home'",
"name": "Name",
"note": "Note: This might not work yet with all integrations.",
"open_device_settings": "Open device settings",
"unavailable": "This entity is not currently available.",
"update": "Update"
},
@@ -1030,7 +1043,7 @@
"confirmation_text": "All devices in this area will become unassigned.",
"confirmation_title": "Are you sure you want to delete this area?"
},
"description": "Manage areas in your home",
"description": "Group devices and entities into areas",
"editor": {
"area_id": "Area ID",
"create": "Create",
@@ -1052,7 +1065,7 @@
},
"automation": {
"caption": "Automations",
"description": "Manage automations",
"description": "Create custom behavior rules for your home",
"dialog_new": {
"blueprint": {
"use_blueprint": "Use a blueprint"
@@ -1400,15 +1413,15 @@
"blueprint": {
"add": {
"error_no_url": "Please enter the URL of the blueprint.",
"file_name": "Local blueprint file name",
"header": "Add new blueprint",
"import_btn": "Import blueprint",
"import_header": "Import \"{name}\" (type: {domain})",
"file_name": "Blueprint Path",
"header": "Import a blueprint",
"import_btn": "Preview blueprint",
"import_header": "Blueprint \"{name}\"",
"import_introduction": "You can import blueprints of other users from Github and the community forums. Enter the URL of the blueprint below.",
"importing": "Importing blueprint...",
"importing": "Loading blueprint...",
"raw_blueprint": "Blueprint content",
"save_btn": "Save blueprint",
"saving": "Saving blueprint...",
"save_btn": "Import blueprint",
"saving": "Importing blueprint...",
"unsupported_blueprint": "This blueprint is not supported",
"url": "URL of the blueprint"
},
@@ -1510,7 +1523,7 @@
"title": "Alexa"
},
"caption": "Home Assistant Cloud",
"description_features": "Control away from home, integrate with Alexa and Google Assistant.",
"description_features": "Control home when away and integrate with Alexa and Google Assistant",
"description_login": "Logged in as {email}",
"description_not_login": "Not logged in",
"dialog_certificate": {
@@ -1605,7 +1618,7 @@
},
"core": {
"caption": "General",
"description": "Change your general Home Assistant configuration",
"description": "Unit system, location, time zone & other general parameters",
"section": {
"core": {
"core_config": {
@@ -1667,6 +1680,7 @@
"unknown_condition": "Unknown condition"
},
"create": "Create automation with device",
"create_disable": "Can't create automation with disabled device",
"no_automations": "No automations",
"no_device_automations": "There are no automations available for this device.",
"triggers": {
@@ -1692,9 +1706,18 @@
"no_devices": "No devices"
},
"delete": "Delete",
"description": "Manage connected devices",
"description": "Manage configured devices",
"device_info": "Device info",
"device_not_found": "Device not found.",
"disabled": "Disabled",
"disabled_by": {
"config_entry": "Config Entry",
"integration": "Integration",
"user": "User"
},
"enabled_cause": "The device is disabled by {cause}.",
"enabled_description": "Disabled devices will not be shown and entities belonging to the device will be disabled and not added to Home Assistant.",
"enabled_label": "Enable device",
"entities": {
"add_entities_lovelace": "Add to Lovelace",
"disabled_entities": "+{count} {count, plural,\n one {disabled entity}\n other {disabled entities}\n}",
@@ -1704,14 +1727,25 @@
},
"name": "Name",
"no_devices": "No devices",
"picker": {
"filter": {
"filter": "Filter",
"hidden_devices": "{number} hidden {number, plural,\n one {device}\n other {devices}\n}",
"show_all": "Show all",
"show_disabled": "Show disabled devices"
},
"search": "Search devices"
},
"scene": {
"create": "Create scene with device",
"create_disable": "Can't create scene with disabled device",
"no_scenes": "No scenes",
"scenes": "Scenes"
},
"scenes": "Scenes",
"script": {
"create": "Create script with device",
"create_disable": "Can't create script with disabled device",
"no_scripts": "No scripts",
"scripts": "Scripts"
},
@@ -1777,7 +1811,7 @@
"header": "Configure Home Assistant",
"helpers": {
"caption": "Helpers",
"description": "Manage elements that help build automations",
"description": "Elements that help build automations",
"dialog": {
"add_helper": "Add helper",
"add_platform": "Add {platform}",
@@ -1809,7 +1843,7 @@
"copy_github": "For GitHub",
"copy_raw": "Raw Text",
"custom_uis": "Custom UIs:",
"description": "View info about your Home Assistant installation",
"description": "Version, system health and links to documentation",
"developed_by": "Developed by a bunch of awesome people.",
"documentation": "Documentation",
"frontend": "frontend-ui",
@@ -1915,7 +1949,7 @@
},
"configure": "Configure",
"configured": "Configured",
"description": "Manage integrations",
"description": "Manage integrations with services, devices, ...",
"details": "Integration details",
"discovered": "Discovered",
"home_assistant_website": "Home Assistant website",
@@ -2000,7 +2034,7 @@
"open": "Open"
}
},
"description": "Manage your Lovelace Dashboards",
"description": "Create customized sets of cards to control your home",
"resources": {
"cant_edit_yaml": "You are using Lovelace in YAML mode, therefore you cannot manage your resources through the UI. Manage them in configuration.yaml.",
"caption": "Resources",
@@ -2199,7 +2233,7 @@
"scene": {
"activated": "Activated scene {name}.",
"caption": "Scenes",
"description": "Manage scenes",
"description": "Capture device states and easily recall them later",
"editor": {
"default_name": "New Scene",
"devices": {
@@ -2243,7 +2277,7 @@
},
"script": {
"caption": "Scripts",
"description": "Manage scripts",
"description": "Execute a sequence of actions",
"editor": {
"alias": "Name",
"default_name": "New Script",
@@ -2354,7 +2388,7 @@
"confirm_remove": "Are you sure you want to remove tag {tag}?",
"confirm_remove_title": "Remove tag?",
"create_automation": "Create automation with tag",
"description": "Manage tags",
"description": "Trigger automations when a NFC tag, QR code, etc. is scanned",
"detail": {
"companion_apps": "companion apps",
"create": "Create",
@@ -2389,10 +2423,11 @@
"username": "Username"
},
"caption": "Users",
"description": "Manage users",
"description": "Manage the Home Assistant user accounts",
"editor": {
"activate_user": "Activate user",
"active": "Active",
"active_tooltip": "Controls if user can login",
"admin": "Administrator",
"caption": "View user",
"change_password": "Change password",
@@ -3411,10 +3446,13 @@
"change_password": {
"confirm_new_password": "Confirm New Password",
"current_password": "Current Password",
"error_new_is_old": "New password must be different than current password",
"error_new_mismatch": "Entered new password values do not match",
"error_required": "Required",
"header": "Change Password",
"new_password": "New Password",
"submit": "Submit"
"submit": "Submit",
"success": "Password changed successfully"
},
"current_user": "You are currently logged in as {fullName}.",
"customize_sidebar": {

View File

@@ -666,6 +666,16 @@
"service-picker": {
"service": "Servicio"
},
"target-picker": {
"add_area_id": "Seleccionar área",
"add_device_id": "Seleccionar dispositivo",
"add_entity_id": "Seleccionar entidad",
"expand_area_id": "Expanda esta área en los dispositivos y entidades independientes que contiene. Después de expandirlo no actualizará los dispositivos y entidades cuando cambie el área.",
"expand_device_id": "Expanda este dispositivo en entidades independientes. Después de expandirlo no actualizará las entidades cuando cambie el dispositivo.",
"remove_area_id": "Eliminar área",
"remove_device_id": "Eliminar dispositivo",
"remove_entity_id": "Eliminar entidad"
},
"user-picker": {
"add_user": "Agregar usuario",
"no_user": "Sin usuario",
@@ -689,6 +699,7 @@
"editor": {
"confirm_delete": "¿Está seguro de que desea eliminar esta entrada?",
"delete": "Eliminar",
"device_disabled": "El dispositivo de esta entidad está deshabilitado.",
"enabled_cause": "Deshabilitado por {cause}.",
"enabled_delay_confirm": "Las entidades habilitadas se agregarán a Home Assistant en {delay} segundos",
"enabled_description": "Las entidades deshabilitadas no serán agregadas a Home Assistant.",
@@ -699,6 +710,7 @@
"icon_error": "Los iconos deben estar en el formato 'prefijo:nombre del icono', por ejemplo, 'mdi: home'",
"name": "Sustituir nombre",
"note": "Nota: esto podría no funcionar todavía con todas las integraciones.",
"open_device_settings": "Abrir la configuración del dispositivo",
"unavailable": "Esta entidad no está disponible actualmente.",
"update": "Actualizar"
},
@@ -1489,6 +1501,7 @@
"unknown_condition": "Condición desconocida"
},
"create": "Crear automatización con dispositivo",
"create_disable": "No se puede crear automatización con un dispositivo deshabilitado",
"no_automations": "Sin automatizaciones",
"no_device_automations": "No hay automatizaciones disponibles para este dispositivo.",
"triggers": {
@@ -1515,6 +1528,14 @@
"description": "Administrar dispositivos conectados",
"device_info": "Información del dispositivo",
"device_not_found": "Dispositivo no encontrado.",
"disabled": "Deshabilitado",
"disabled_by": {
"config_entry": "Entrada de configuración",
"integration": "Integración",
"user": "Usuario"
},
"enabled_description": "Los dispositivos deshabilitados no se mostrarán y las entidades que pertenecen al dispositivo se deshabilitarán y no se agregarán a Home Assistant.",
"enabled_label": "Habilitar dispositivo",
"entities": {
"add_entities_lovelace": "Agregar a Lovelace",
"disabled_entities": "+{count} {count, plural,\n one {entidad deshabilitada}\n other {entidades deshabilitadas}\n}",
@@ -1524,14 +1545,24 @@
},
"name": "Nombre",
"no_devices": "Sin dispositivos",
"picker": {
"filter": {
"filter": "Filtrar",
"show_all": "Mostrar todo",
"show_disabled": "Mostrar los dispositivos deshabilitadas"
},
"search": "Mostrar dispositivos"
},
"scene": {
"create": "Crear escena con dispositivo",
"create_disable": "No se puede crear una escena con un dispositivo deshabilitado",
"no_scenes": "Sin escenas",
"scenes": "Escenas"
},
"scenes": "Escenas",
"script": {
"create": "Crear script con dispositivo",
"create_disable": "No se puede crear un script con un dispositivo deshabilitado",
"no_scripts": "Sin scripts",
"scripts": "Scripts"
},
@@ -2168,6 +2199,7 @@
"editor": {
"activate_user": "Activar usuario",
"active": "Activo",
"active_tooltip": "Controla si el usuario puede iniciar sesión",
"admin": "Administrador",
"caption": "Ver usuario",
"change_password": "Cambiar contraseña",
@@ -3136,10 +3168,13 @@
"change_password": {
"confirm_new_password": "Confirmar nueva contraseña",
"current_password": "Contraseña actual",
"error_new_is_old": "La nueva contraseña debe ser diferente a la contraseña actual",
"error_new_mismatch": "Las contraseñas no coinciden",
"error_required": "Necesario",
"header": "Cambiar contraseña",
"new_password": "Nueva contraseña",
"submit": "Enviar"
"submit": "Enviar",
"success": "La contraseña se cambió con éxito"
},
"current_user": "Actualmente estás conectado como {fullName} .",
"customize_sidebar": {

View File

@@ -2,6 +2,7 @@
"config_entry": {
"disabled_by": {
"config_entry": "Entrada de configuración",
"device": "Dispositivo",
"integration": "Integración",
"user": "Usuario"
}
@@ -710,6 +711,16 @@
"service-picker": {
"service": "Servicio"
},
"target-picker": {
"add_area_id": "Seleccionar área",
"add_device_id": "Seleccionar dispositivo",
"add_entity_id": "Seleccionar entidad",
"expand_area_id": "Expande este área en los dispositivos y entidades independientes que contiene. Después de expandirse, no actualizará los dispositivos y entidades cuando cambie el área.",
"expand_device_id": "Expande este dispositivo en entidades separadas. Después de expandirse, no actualizará las entidades cuando cambie el dispositivo.",
"remove_area_id": "Eliminar área",
"remove_device_id": "Eliminar dispositivo",
"remove_entity_id": "Eliminar entidad"
},
"user-picker": {
"add_user": "Añadir usuario",
"no_user": "Sin usuario",
@@ -733,6 +744,7 @@
"editor": {
"confirm_delete": "¿Estás seguro de que quieres eliminar este elemento?",
"delete": "Eliminar",
"device_disabled": "El dispositivo de esta entidad está deshabilitado.",
"enabled_cause": "Desactivado por {cause}.",
"enabled_delay_confirm": "Las entidades habilitadas se agregarán a Home Assistant en {delay} segundos",
"enabled_description": "Las entidades deshabilitadas no se agregarán a Home Assistant.",
@@ -743,6 +755,7 @@
"icon_error": "Los iconos deben tener el formato 'prefijo:nombreicono', por ejemplo, 'mdi:home'",
"name": "Nombre",
"note": "Nota: puede que esto no funcione todavía con todas las integraciones",
"open_device_settings": "Abrir la configuración del dispositivo",
"unavailable": "Esta entidad no está disponible actualmente.",
"update": "Actualizar"
},
@@ -1030,7 +1043,7 @@
"confirmation_text": "Todos los dispositivos en esta área quedarán sin asignar.",
"confirmation_title": "¿Estás seguro de que deseas eliminar esta área?"
},
"description": "Administra áreas en tu hogar",
"description": "Agrupa dispositivos en áreas",
"editor": {
"area_id": "ID de área",
"create": "Crear",
@@ -1052,7 +1065,7 @@
},
"automation": {
"caption": "Automatizaciones",
"description": "Administra las automatizaciones",
"description": "Crea reglas de comportamiento personalizadas para tu hogar",
"dialog_new": {
"blueprint": {
"use_blueprint": "Usa un plano"
@@ -1510,7 +1523,7 @@
"title": "Alexa"
},
"caption": "Nube Home Assistant",
"description_features": "Control fuera de casa, integración con Alexa y Google Assistant.",
"description_features": "Controla tu hogar cuando estés fuera e intégralo con Alexa y Google Assistant",
"description_login": "Has iniciado sesión como {email}",
"description_not_login": "No has iniciado sesión",
"dialog_certificate": {
@@ -1605,7 +1618,7 @@
},
"core": {
"caption": "Configuración general",
"description": "Cambia la configuración general de Home Assistant",
"description": "Sistema de unidades, ubicación, zona horaria y otros parámetros generales",
"section": {
"core": {
"core_config": {
@@ -1667,6 +1680,7 @@
"unknown_condition": "Condición desconocida"
},
"create": "Crear automatización con el dispositivo",
"create_disable": "No se puede crear una automatización con un dispositivo deshabilitado",
"no_automations": "Sin automatizaciones",
"no_device_automations": "No hay automatizaciones disponibles para este dispositivo.",
"triggers": {
@@ -1692,9 +1706,18 @@
"no_devices": "Sin dispositivos"
},
"delete": "Eliminar",
"description": "Administrar dispositivos conectados",
"description": "Administra dispositivos configurados",
"device_info": "Información del dispositivo",
"device_not_found": "Dispositivo no encontrado.",
"disabled": "Deshabilitado",
"disabled_by": {
"config_entry": "Entrada de configuración",
"integration": "Integración",
"user": "Usuario"
},
"enabled_cause": "El dispositivo está deshabilitado por {cause} .",
"enabled_description": "Los dispositivos deshabilitados no se mostrarán y las entidades que pertenecen al dispositivo se deshabilitarán y no se añadirán a Home Assistant.",
"enabled_label": "Habilitar dispositivo",
"entities": {
"add_entities_lovelace": "Añadir a Lovelace",
"disabled_entities": "+{count} {count, plural,\n one {entidad deshabilitada}\n other {entidades deshabilitadas}\n}",
@@ -1704,14 +1727,25 @@
},
"name": "Nombre",
"no_devices": "Sin dispositivos",
"picker": {
"filter": {
"filter": "Filtrar",
"hidden_devices": "{number} {number, plural,\n one {dispositivo oculto}\n other {dispositivos ocultos}\n}",
"show_all": "Mostrar todo",
"show_disabled": "Mostrar dispositivos deshabilitados"
},
"search": "Buscar dispositivos"
},
"scene": {
"create": "Crear escena con el dispositivo",
"create_disable": "No se puede crear una escena con un dispositivo deshabilitado",
"no_scenes": "Sin escenas",
"scenes": "Escenas"
},
"scenes": "Escenas",
"script": {
"create": "Crear script con el dispositivo",
"create_disable": "No se puede crear un script con un dispositivo deshabilitado",
"no_scripts": "Sin scripts",
"scripts": "Scripts"
},
@@ -1744,6 +1778,7 @@
},
"header": "Entidades",
"headers": {
"area": "Área",
"entity_id": "ID de entidad",
"integration": "Integración",
"name": "Nombre",
@@ -1776,7 +1811,7 @@
"header": "Configurar Home Assistant",
"helpers": {
"caption": "Ayudantes",
"description": "Administra los elementos que pueden ayudar a construir automatizaciones.",
"description": "Elementos que ayudan a construir automatizaciones",
"dialog": {
"add_helper": "Añadir ayudante",
"add_platform": "Añadir {platform}",
@@ -1808,7 +1843,7 @@
"copy_github": "Para GitHub",
"copy_raw": "Texto sin procesar",
"custom_uis": "IU personalizadas:",
"description": "Ver información sobre tu instalación de Home Assistant",
"description": "Versión, estado del sistema y enlaces a la documentación",
"developed_by": "Desarrollado por un montón de gente impresionante.",
"documentation": "Documentación",
"frontend": "interfaz de usuario",
@@ -1914,7 +1949,7 @@
},
"configure": "Configurar",
"configured": "Configurado",
"description": "Administra las integraciones",
"description": "Gestiona integraciones con servicios, dispositivos, ...",
"details": "Detalles de la integración",
"discovered": "Descubierto",
"home_assistant_website": "Sitio web de Home Assistant",
@@ -1999,7 +2034,7 @@
"open": "Abrir"
}
},
"description": "Administra tus Paneles de Control Lovelace",
"description": "Crea conjuntos personalizados de tarjetas para controlar tu hogar",
"resources": {
"cant_edit_yaml": "Estás utilizando Lovelace en modo YAML, por tanto no puedes administrar tus recursos a través de la IU. Adminístralos en configuration.yaml.",
"caption": "Recursos",
@@ -2198,7 +2233,7 @@
"scene": {
"activated": "Activada escena {name}.",
"caption": "Escenas",
"description": "Administra las escenas",
"description": "Captura los estados de los dispositivos y recupéralos fácilmente más tarde",
"editor": {
"default_name": "Nueva Escena",
"devices": {
@@ -2242,7 +2277,7 @@
},
"script": {
"caption": "Scripts",
"description": "Administra los scripts",
"description": "Ejecuta una secuencia de acciones",
"editor": {
"alias": "Nombre",
"default_name": "Nuevo script",
@@ -2353,7 +2388,7 @@
"confirm_remove": "¿Estás seguro de que quieres eliminar la etiqueta {tag} ?",
"confirm_remove_title": "¿Eliminar etiqueta?",
"create_automation": "Crear automatización con etiqueta",
"description": "Administrar etiquetas",
"description": "Activa automatizaciones cuando se escanea una etiqueta NFC, un código QR, etc.",
"detail": {
"companion_apps": "aplicaciones complementarias",
"create": "Crear",
@@ -2392,6 +2427,7 @@
"editor": {
"activate_user": "Activar usuario",
"active": "Activo",
"active_tooltip": "Controla si el usuario puede iniciar sesión",
"admin": "Administrador",
"caption": "Ver usuario",
"change_password": "Cambiar la contraseña",
@@ -2471,6 +2507,16 @@
"value": "Valor"
},
"description": "Administración de red de Domótica Zigbee",
"device_pairing_card": {
"CONFIGURED": "Configuración completada",
"CONFIGURED_status_text": "Inicializando",
"INITIALIZED": "Inicialización completada",
"INITIALIZED_status_text": "El dispositivo está listo para ser usado",
"INTERVIEW_COMPLETE": "Entrevista completada",
"INTERVIEW_COMPLETE_status_text": "Configurando",
"PAIRED": "Dispositivo encontrado",
"PAIRED_status_text": "Iniciando entrevista"
},
"devices": {
"header": "Domótica Zigbee - Dispositivo"
},
@@ -3400,10 +3446,13 @@
"change_password": {
"confirm_new_password": "Confirmar nueva contraseña",
"current_password": "Contraseña actual",
"error_new_is_old": "La nueva contraseña debe ser diferente a la contraseña actual",
"error_new_mismatch": "Los nuevos valores de contraseña introducidos no coinciden",
"error_required": "Obligatorio",
"header": "Cambiar contraseña",
"new_password": "Nueva contraseña",
"submit": "Enviar"
"submit": "Enviar",
"success": "Contraseña cambiada con éxito"
},
"current_user": "Has iniciado sesión como {fullName}.",
"customize_sidebar": {

View File

@@ -2,6 +2,7 @@
"config_entry": {
"disabled_by": {
"config_entry": "Seade kanne",
"device": "Seade",
"integration": "Sidumine",
"user": "Kasutaja"
}
@@ -710,6 +711,16 @@
"service-picker": {
"service": "Teenus"
},
"target-picker": {
"add_area_id": "Vali ala",
"add_device_id": "Vali seade",
"add_entity_id": "Vali olem",
"expand_area_id": "Laienda seda ala eraldi seadmetesse jaolemitesse mis sellesse kuuluvad. Pärast laiendamist ei värskendata seadmeid ja olemeid, kui ala muutub.",
"expand_device_id": "Laienda seda seadet eraldi olemitesse. Pärast laiendamist ei värskendata olemeid, kui seade muutub.",
"remove_area_id": "Eemalda ala",
"remove_device_id": "Eemalda seade",
"remove_entity_id": "Eemalda olem"
},
"user-picker": {
"add_user": "Lisa kasutaja",
"no_user": "Kasutaja puudub",
@@ -733,6 +744,7 @@
"editor": {
"confirm_delete": "Oled kindel, et soovid selle kirje kustutada?",
"delete": "Kustuta",
"device_disabled": "Selle olemi seade on keelatud.",
"enabled_cause": "Keelatud, sest {cause}.",
"enabled_delay_confirm": "Lubatud üksused lisatakse Home Assistanti {delay} sekundi pärast",
"enabled_description": "Keelatud olemeid ei lisata Home Assistant'i.",
@@ -743,6 +755,7 @@
"icon_error": "Ikoonid peaksid olema vormingus 'prefix: iconname', nt 'mdi: home'",
"name": "Nime muutmine",
"note": "Märkus: see ei pruugi veel töötada kõigi sidumistega.",
"open_device_settings": "Seadme sätete avamine",
"unavailable": "See olem pole praegu saadaval.",
"update": "Uuenda"
},
@@ -1030,7 +1043,7 @@
"confirmation_text": "Kõik sellele ala seadmed jäävad peremehetuks.",
"confirmation_title": "Oled kindel, et soovid selle ala kustutada?"
},
"description": "Ülevaade kõikidest oma kodu aladest.",
"description": "Seadmete rühmitamine aladesse",
"editor": {
"area_id": "Piirkonna ID",
"create": "LOO",
@@ -1052,7 +1065,7 @@
},
"automation": {
"caption": "Automatiseeringud",
"description": "Loo ja redigeeri automatiseeringuid",
"description": "Loo oma kodu jaoks kohandatud käitumisreeglid",
"dialog_new": {
"blueprint": {
"use_blueprint": "Kasuta kavandit"
@@ -1456,7 +1469,7 @@
"enable_state_reporting": "Lubada olekuteavitused",
"enter_pin_error": "PIN-koodi ei saa salvestada:",
"enter_pin_hint": "Turvaseadmete kasutamiseks sisesta PIN",
"enter_pin_info": "Turvaseadmetega suhtlemiseks sisestage PIN-kood. Turvaseadmed on uksed, garaažiuksed ja lukud. Google Assistanti kaudu selliste seadmetega suheldes palutakse Teil see PIN-kood öelda / sisestada.",
"enter_pin_info": "Turvaseadmetega suhtlemiseks sisesta PIN-kood. Turvaseadmed on uksed, garaažiuksed ja lukud. Google Assistanti kaudu selliste seadmetega suheldes palutakse Teil see PIN-kood öelda / sisestada.",
"info": "Google Assistanti integreerimisel läbi Home Assistant Cloudi saate juhtida kõiki oma Home Assistanti seadmeid mis tahes Google Assistanti toega seadme kaudu.",
"info_state_reporting": "Kui lubate olekute avaldamise, saadab Home Assistant Google'ile kõik avaldatud olemite olekumuutused. See võimaldab Teil alati näha Google'i rakenduses uusimaid olekuid.",
"manage_entities": "Halda olemeid",
@@ -1478,7 +1491,7 @@
"info": "Home Assistant Cloud pakub turvalist kaugühendust teie Home Assistantiga kodust eemal olles.",
"instance_is_available": "Teie Home Assistant on saadaval aadressil",
"instance_will_be_available": "Teie Home Assistanti on aadressiks saab",
"link_learn_how_it_works": "Loe, kuidas see töötab",
"link_learn_how_it_works": "Loe kuidas see töötab",
"title": "Kaugjuhtimine"
},
"sign_out": "Logi välja",
@@ -1535,7 +1548,7 @@
"check_your_email": "Parooli lähtestamise kohta saate juhiseid oma e-posti aadressilt.",
"email": "E-post",
"email_error_msg": "Vigane meiliaadress",
"instructions": "Sisestage oma e-posti aadress ja me saadame teile lingi parooli lähtestamiseks.",
"instructions": "Sisesta oma e-posti aadress ja me saadame teile lingi parooli lähtestamiseks.",
"send_reset_email": "Saatke lähtestamismeil",
"subtitle": "Unustasid oma salasõna",
"title": "Unustasid salasõna"
@@ -1605,7 +1618,7 @@
},
"core": {
"caption": "Üldine",
"description": "Home Assistant'i üldiste seadete muutmine",
"description": "Ühikud, asukoht, ajavöönd ja muud üldised parameetrid",
"section": {
"core": {
"core_config": {
@@ -1667,6 +1680,7 @@
"unknown_condition": "Tundmatu tingimus"
},
"create": "Loo seadmega automatiseering",
"create_disable": "Keelatud seadmega ei saa automaatiseeringuid luua",
"no_automations": "Automatiseeringuid pole",
"no_device_automations": "Selle seadme jaoks pole automatiseerimisi saadaval.",
"triggers": {
@@ -1692,9 +1706,18 @@
"no_devices": "Seadmeid pole"
},
"delete": "Kustuta",
"description": "Halda ühendatud seadmeid",
"description": "Halda häälestatud seadmeid",
"device_info": "Seadme info",
"device_not_found": "Seadet ei leitud.",
"disabled": "Keelatud",
"disabled_by": {
"config_entry": "Seade kanne",
"integration": "Sidumine",
"user": "Kasutaja"
},
"enabled_cause": "{cause} on seadme keelanud.",
"enabled_description": "Keelatud seadmeid ei kuvata ja seadmele kuuluvad olemid keelatakse ning neid ei lisata Home Assistantile.",
"enabled_label": "Luba seade",
"entities": {
"add_entities_lovelace": "Lisa Lovelace'i",
"disabled_entities": "{count} {count, plural,\n one {keelatud olem}\n other {keelatud olemit}\n}",
@@ -1704,14 +1727,25 @@
},
"name": "Nimi",
"no_devices": "Seadmeid pole",
"picker": {
"filter": {
"filter": "Filtreeri",
"hidden_devices": "{number} peidetud {number, plural,\n one {olem}\n other {olemit}\n}",
"show_all": "Kuva kõik",
"show_disabled": "Kuva keelatud seadmed"
},
"search": "Otsi seadmeid"
},
"scene": {
"create": "Loo seadmega stseen",
"create_disable": "Keelatud seadmega ei saa stseene luua",
"no_scenes": "Stseene pole",
"scenes": "Stseenid"
},
"scenes": "Stseenid",
"script": {
"create": "Loo seadmega skript",
"create_disable": "Keelatud seadmega ei saa skripte luua",
"no_scripts": "Skripte pole",
"scripts": "Skriptid"
},
@@ -1744,6 +1778,7 @@
},
"header": "Olemid",
"headers": {
"area": "Ala",
"entity_id": "Olemi ID",
"integration": "Sidumine",
"name": "Nimi",
@@ -1776,7 +1811,7 @@
"header": "Home Assistant'i seadistamine",
"helpers": {
"caption": "Abimehed",
"description": "Hallake elemente mis aitavad automatiseeringuid luua",
"description": "Elemendid mis aitavad automatiseeringuid luua",
"dialog": {
"add_helper": "Lisage abistaja",
"add_platform": "Lisa {platform}",
@@ -1808,7 +1843,7 @@
"copy_github": "GitHubi jaoks",
"copy_raw": "Ainult tekst",
"custom_uis": "Kohandatud kasutajaliidesed:",
"description": "Kuva Home Assistant'i info",
"description": "Versioon, süsteemi olek ja lingid dokumentatsioonile",
"developed_by": "Tehtud paljude lahedate inimeste poolt.",
"documentation": "Dokumentatsioon",
"frontend": "frontend-ui",
@@ -1826,9 +1861,9 @@
"checks": {
"cloud": {
"alexa_enabled": "Alexa on lubatud",
"can_reach_cert_server": "Ühendu serdiserveriga",
"can_reach_cloud": "Ühendu Home Assistant Cloudiga",
"can_reach_cloud_auth": "Ühendu tuvastusserveriga",
"can_reach_cert_server": "Ühendus serdiserveriga",
"can_reach_cloud": "Ühendus Home Assistant Cloudiga",
"can_reach_cloud_auth": "Ühendus tuvastusserveriga",
"google_enabled": "Google on lubatud",
"logged_in": "Sisse logitud",
"relayer_connected": "Edastaja on ühendatud",
@@ -1914,7 +1949,7 @@
},
"configure": "Seadista",
"configured": "Seadistatud",
"description": "Halda ja seadista sidumisi",
"description": "Halda teenuste, seadmete jne. sidumisi",
"details": "Sidumise üksikasjad",
"discovered": "Leitud",
"home_assistant_website": "Home Assistant veebisait",
@@ -1999,7 +2034,7 @@
"open": "Ava"
}
},
"description": "Hallake oma Lovelace juhtpaneele",
"description": "Loo oma kodu juhtimiseks kohandatud juhtpaneele",
"resources": {
"cant_edit_yaml": "Kasutate Lovelace YAML režiimis. Seega ei saa Te hallata oma ressursse kasutajaliidese kaudu. Halda neid kirjes configuration.yaml.",
"caption": "Ressursid",
@@ -2198,7 +2233,7 @@
"scene": {
"activated": "Stseen {name} on käivitatud.",
"caption": "Stseenid",
"description": "Loo ja muuda stseene",
"description": "Seadme olekute hõivamine ja nende hilisem taaskasutamine",
"editor": {
"default_name": "Uus stseen",
"devices": {
@@ -2242,7 +2277,7 @@
},
"script": {
"caption": "Skriptid",
"description": "Loo ja muuda skripte",
"description": "Vallanda toimingute jada",
"editor": {
"alias": "Nimi",
"default_name": "Uus skript",
@@ -2292,7 +2327,7 @@
},
"server_control": {
"caption": "Serveri juhtimine",
"description": "Taaskäivita ja peata Home Assistant server",
"description": "Taaskäivita ja peata Home Assistant serverit",
"section": {
"reloading": {
"automation": "Taaslae automatiseeringud",
@@ -2330,7 +2365,7 @@
"zone": "Taaslae tsoonid"
},
"server_management": {
"confirm_restart": "Oled kindel, et soovid taaskäivitada Home Assistant'i?",
"confirm_restart": "Oled kindel, et soovid Home Assistant'i taaskäivitada?",
"confirm_stop": "Oled kindel, et soovid seisata Home Assistant'i?",
"heading": "Serveri haldamine",
"introduction": "Kontrolli oma Home Assistant serverit... Home Assistant'ist.",
@@ -2353,7 +2388,7 @@
"confirm_remove": "Kas soovid kindlasti eemaldada märgise {tag}?",
"confirm_remove_title": "Kas kustutan märgise?",
"create_automation": "Lisa automatiseering TAG abil",
"description": "Halda TAGe",
"description": "Käivita automaatiseering NFC-sildi, QR-koodi jne. skännimisel",
"detail": {
"companion_apps": "mobiilirakendused",
"create": "Loo",
@@ -2392,6 +2427,7 @@
"editor": {
"activate_user": "Aktiveeri kasutaja",
"active": "Aktiivne",
"active_tooltip": "Määrab kas kasutaja saab sisse logida",
"admin": "Administraator",
"caption": "Vaata kasutajat",
"change_password": "Muuda salasõna",
@@ -2471,6 +2507,16 @@
"value": "Väärtus"
},
"description": "Zigbee Home Automation võrgu haldamine",
"device_pairing_card": {
"CONFIGURED": "Seadistamine on lõpetatud",
"CONFIGURED_status_text": "Lähtestan",
"INITIALIZED": "Lähtestamine on lõpetatud",
"INITIALIZED_status_text": "Seade on kasutamiseks valmis",
"INTERVIEW_COMPLETE": "Küsitlemine on lõpetatud",
"INTERVIEW_COMPLETE_status_text": "Seadistan",
"PAIRED": "Seade on leitud",
"PAIRED_status_text": "Alustan küsitlemist"
},
"devices": {
"header": "Zigbee Home Automation - Seade"
},
@@ -2492,7 +2538,7 @@
"caption": "Grupid",
"create": "Loo grupp",
"create_group": "Zigbee Home Automation - Loo grupp",
"create_group_details": "Sisestage uue zigbee grupi loomiseks vajalikud üksikasjad.",
"create_group_details": "Sisesta uue Zigbee grupi loomiseks vajalikud üksikasjad.",
"creating_group": "Loon gruppi",
"description": "Loo ja muuda Zigbee gruppe",
"group_details": "Siin on kõik valitud Zigbee rühma üksikasjad.",
@@ -2821,7 +2867,7 @@
},
"calendar": {
"calendar_entities": "Kalendri olemid",
"description": "Kalendri kaardil kuvatakse kalender mis sisaldab päeva, nädala ja loendivaateid",
"description": "Kalendri kaardil kuvatakse kalender mis sisaldab päeva-, nädala- ja loendivaateid",
"inital_view": "Vaikevaade",
"name": "Kalender",
"views": {
@@ -2846,7 +2892,7 @@
"required": "Nõutav"
},
"entities": {
"description": "Olemite kaart on kõige levinum kaarditüüp. See rühmitabolemid loenditeks.",
"description": "Olemite kaart on kõige levinum kaarditüüp. See rühmitab olemid loenditeks.",
"edit_special_row": "Selle rea üksikasjade vaatamiseks klõpsa nuppu Muuda",
"entity_row_editor": "Olemirea redaktor",
"entity_row": {
@@ -2876,7 +2922,7 @@
"toggle": "Vaheta olemeid."
},
"entity-filter": {
"description": "Olemifiltri kaart võimaldab teil määratleda nende olemite loendit mida soovite jälgida ainult teatud olekus.",
"description": "Olemifiltri kaart võimaldab teil määratleda nende olemite loendit mida soovid jälgida ainult teatud olekus.",
"name": "Olemi filter"
},
"entity": {
@@ -3400,10 +3446,13 @@
"change_password": {
"confirm_new_password": "Kinnita uut salasõna",
"current_password": "Praegune salasõna",
"error_new_is_old": "Uus salasõna peab praegusest erinema",
"error_new_mismatch": "Sisestatud uus salasõna ei ühti",
"error_required": "Nõutav",
"header": "Muuda salasõna",
"new_password": "Uus salasõna",
"submit": "Esita"
"submit": "Esita",
"success": "Salasõna muutmine õnnestus"
},
"current_user": "Oled praegu sisse logitud kui {fullName}.",
"customize_sidebar": {

View File

@@ -1680,7 +1680,7 @@
"caption": "Appareils",
"confirm_delete": "Voulez-vous vraiment supprimer cet appareil ?",
"confirm_rename_entity_ids": "Voulez-vous aussi renommer les ID de vos entités?",
"confirm_rename_entity_ids_warning": "Cela ne changera aucune configuration (comme les automatismes, les scripts, les scènes, Lovelace) qui utilisent actuellement ces entités, vous devrez les mettre à jour vous-même.",
"confirm_rename_entity_ids_warning": "Cela ne changera aucune configuration (comme les automatisations, les scripts, les scènes, Lovelace) qui utilisent actuellement ces entités, vous devrez les mettre à jour vous-même.",
"data_table": {
"area": "Zone",
"battery": "Batterie",
@@ -1744,6 +1744,7 @@
},
"header": "Entités",
"headers": {
"area": "Pièce",
"entity_id": "ID de l'entité",
"integration": "Intégration",
"name": "Nom",
@@ -2471,6 +2472,16 @@
"value": "Valeur"
},
"description": "Gestion de réseau domotique Zigbee",
"device_pairing_card": {
"CONFIGURED": "Configuration terminée",
"CONFIGURED_status_text": "Initialisation",
"INITIALIZED": "Initialisation terminée",
"INITIALIZED_status_text": "L'appareil est prêt à être utilisé",
"INTERVIEW_COMPLETE": "Processus d'interrogation terminé",
"INTERVIEW_COMPLETE_status_text": "Configurer",
"PAIRED": "Appareil trouvé",
"PAIRED_status_text": "Démarrage du processus d'interrogation"
},
"devices": {
"header": "Zigbee Home Automation - Appareil"
},
@@ -3358,7 +3369,7 @@
"button_detect": "Détecter",
"finish": "Suivant",
"intro": "Bonjour {name}, bienvenue dans Home Assistant. Comment voudriez-vous nommer votre maison?",
"intro_location": "Nous aimerions savoir où vous habitez. Ces informations vous aideront à afficher des informations et à configurer des automatismes basés sur le soleil. Ces données ne sont jamais partagées en dehors de votre réseau.",
"intro_location": "Nous aimerions savoir où vous habitez. Ces informations vous aideront à afficher des informations et à configurer des automatisations basés sur le soleil. Ces données ne sont jamais partagées en dehors de votre réseau.",
"intro_location_detect": "Nous pouvons vous aider à renseigner ces informations en adressant une demande unique à un service externe.",
"location_name": "Nom de votre installation Home Assistant",
"location_name_default": "Maison"

View File

@@ -1744,6 +1744,7 @@
},
"header": "Entità",
"headers": {
"area": "Area",
"entity_id": "ID entità",
"integration": "Integrazione",
"name": "Nome",
@@ -2471,6 +2472,16 @@
"value": "Valore"
},
"description": "Gestione rete Zigbee Home Automation",
"device_pairing_card": {
"CONFIGURED": "Configurazione completata",
"CONFIGURED_status_text": "Inizializzazione",
"INITIALIZED": "Inizializzazione completata",
"INITIALIZED_status_text": "Il dispositivo è pronto per l'uso",
"INTERVIEW_COMPLETE": "Interrogazione completata",
"INTERVIEW_COMPLETE_status_text": "Configurazione",
"PAIRED": "Dispositivo trovato",
"PAIRED_status_text": "Inizio interrogazione"
},
"devices": {
"header": "Zigbee Home Automation - Dispositivo"
},
@@ -2811,8 +2822,8 @@
"card": {
"alarm-panel": {
"available_states": "Stati disponibili",
"description": "La scheda del pannello di allarme consente di Attivare e Disattivare le tue integrazioni del pannello di controllo di allarme.",
"name": "Pannello di allarme"
"description": "La scheda del Pannello di Allarme consente di attivare e disattivare le tue integrazioni del pannello di controllo allarme.",
"name": "Pannello di Allarme"
},
"button": {
"default_action_help": "L'azione predefinita dipende dalle capacità dell'entità, verrà attivata o disattivata o verranno mostrate più informazioni.",
@@ -2876,7 +2887,7 @@
"toggle": "Attiva/disattiva entità."
},
"entity-filter": {
"description": "La scheda Filtro Entità consente di definire un elenco di entità che si desidera monitorare solo in un determinato stato.",
"description": "La scheda Filtro Entità consente di definire un elenco di entità che si desidera monitorare quando sono solamente in un determinato stato.",
"name": "Filtro Entità"
},
"entity": {
@@ -2884,10 +2895,10 @@
"name": "Entità"
},
"gauge": {
"description": "La scheda Indicatore è una scheda di base che consente di visualizzare visivamente i dati del sensore.",
"description": "La scheda Indicatore è una scheda di base che consente di visualizzare i dati di un sensore.",
"name": "Indicatore",
"severity": {
"define": "Definire la gravità?",
"define": "Definire l'intensità?",
"green": "Verde",
"red": "Rosso",
"yellow": "Giallo"
@@ -2899,15 +2910,15 @@
"camera_image": "Entità Fotocamera",
"camera_view": "Vista fotocamera",
"double_tap_action": "Azione doppio tocco",
"entities": "Entità",
"entity": "Entità",
"hold_action": "Azione di attesa",
"entities": "Molte Entità",
"entity": "Singola Entità",
"hold_action": "Azione tocco prolungato",
"hours_to_show": "Ore da mostrare",
"icon": "Icona",
"icon_height": "Altezza icona",
"image": "Percorso immagine",
"manual": "Manuale",
"manual_description": "Devi aggiungere una scheda personalizzata o semplicemente si vuole scrivere manualmente il file in yaml?",
"manual_description": "Devi aggiungere una scheda personalizzata o vuoi semplicemente scrivere manualmente il file in yaml?",
"maximum": "Massimo",
"minimum": "Minimo",
"name": "Nome",
@@ -2920,7 +2931,7 @@
"show_state": "Mostrare lo stato?",
"state": "Stato",
"state_color": "Colorare le icone in base allo stato?",
"tap_action": "Tocca Azione",
"tap_action": "Azione tocco",
"theme": "Tema",
"title": "Titolo",
"unit": "Unità",
@@ -2937,27 +2948,27 @@
},
"history-graph": {
"description": "La scheda Grafico Storico consente di visualizzare un grafico per ciascuna delle entità elencate.",
"name": "Grafico cronologico"
"name": "Grafico Storico"
},
"horizontal-stack": {
"description": "La scheda Pila Orizzontale consente di raggruppare insieme più schede, in modo che siano sempre l'una accanto all'altra nello spazio di una colonna.",
"name": "Pila orizzontale"
},
"humidifier": {
"description": "La scheda Umidificatore fornisce il controllo della tua entità umidificatore, consentendo di modificare l'umidità e la modalità dell'entità.",
"description": "La scheda Umidificatore fornisce il controllo della tua entità umidificatore. Ti consente di modificare l'umidità e la modalità di funzionamento dell'entità.",
"name": "Umidificatore"
},
"iframe": {
"description": "La scheda Pagina Web consente di incorporare la pagina Web preferita direttamente in Home Assistant.",
"name": "Pagina web"
"description": "La scheda Pagina Web consente di incorporare la tua pagina web preferita direttamente in Home Assistant.",
"name": "Pagina Web"
},
"light": {
"description": "La scheda Luce consente di modificare la luminosità della luce.",
"name": "Luce"
},
"logbook": {
"description": "La scheda del Diario di bordo mostra un elenco di eventi per le entità.",
"name": "Diario di bordo"
"description": "La scheda Registro mostra un elenco di eventi per le entità.",
"name": "Registro"
},
"map": {
"dark_mode": "Modalità scura?",
@@ -2970,7 +2981,7 @@
},
"markdown": {
"content": "Contenuto",
"description": "La scheda Ribassi viene utilizzata per presentare i ribassi.",
"description": "La scheda Markdown viene utilizzata per eseguire il rendering di testo scritto in linguaggio Markdown per una gradevole formattazione della visualizzazione.",
"name": "Markdown"
},
"media-control": {
@@ -2987,7 +2998,7 @@
},
"picture-glance": {
"description": "La scheda Occhiata Immagine mostra un'immagine e gli stati dell'entità corrispondenti come una icona. Le entità sul lato destro consentono azioni di commutazione, altre mostrano più informazioni di dialogo.",
"name": "Vista immagine",
"name": "Sguardo d'Immagine",
"state_entity": "Stato Entità"
},
"picture": {
@@ -2996,7 +3007,7 @@
},
"plant-status": {
"description": "La scheda dello Stato della Pianta è per tutti gli adorabili botanici là fuori.",
"name": "Stato pianta"
"name": "Stato della Pianta"
},
"sensor": {
"description": "La scheda Sensore offre una rapida panoramica dello stato dei sensori con un grafico opzionale per visualizzare il cambiamento nel tempo.",
@@ -3006,7 +3017,7 @@
"show_more_detail": "Mostra ulteriori dettagli"
},
"shopping-list": {
"description": "La scheda della Lista della Spesa consente di aggiungere, modificare, selezionare e cancellare gli articoli dalla lista della spesa.",
"description": "La scheda Lista della Spesa consente di aggiungere, modificare, selezionare e cancellare gli articoli dalla tua lista della spesa.",
"integration_not_loaded": "Questa carta richiede l'integrazione \"shopping_list\" per essere configurata.",
"name": "Lista della spesa"
},
@@ -3055,7 +3066,7 @@
"options": "Altre opzioni",
"pick_card": "Quale scheda vorresti aggiungere?",
"pick_card_view_title": "Quale scheda vorresti aggiungere alla tua vista {name}?",
"search_cards": "Schede di ricerca",
"search_cards": "Cerca schede",
"show_code_editor": "Mostra Editor di Codice",
"show_visual_editor": "Mostra Editor Visivo",
"toggle_editor": "Attiva / disattiva l'editor",

View File

@@ -7,6 +7,7 @@
}
},
"groups": {
"owner": "소유자",
"system-admin": "관리자",
"system-read-only": "읽기 전용 사용자",
"system-users": "사용자"
@@ -332,13 +333,13 @@
"zwave": {
"default": {
"dead": "응답없음",
"initializing": "초기화중",
"initializing": "초기화 중",
"ready": "준비",
"sleeping": "절전모드"
},
"query_stage": {
"dead": "응답없음 ({query_stage})",
"initializing": "초기화중 ({query_stage})"
"initializing": "초기화 중 ({query_stage})"
}
}
},
@@ -747,6 +748,7 @@
"edit": "구성요소 편집",
"history": "기록 내용",
"last_changed": "최근 변경 됨",
"last_updated": "최근 업데이트 됨",
"person": {
"create_zone": "현재 위치로 지역 만들기"
},
@@ -807,6 +809,7 @@
"navigation": {
"areas": "영역",
"automation": "자동화",
"blueprint": "블루프린트",
"core": "일반",
"customize": "사용자화",
"devices": "기기",
@@ -972,6 +975,13 @@
"automation": {
"caption": "자동화",
"description": "자동화를 관리합니다",
"dialog_new": {
"start_empty": "빈 자동화로 시작하기",
"thingtalk": {
"create": "만들기",
"input_label": "이 자동화로 무엇을 하시겠습니까?"
}
},
"editor": {
"actions": {
"add": "동작 추가",
@@ -1052,6 +1062,14 @@
"unsupported_action": "UI 미지원 동작: {action}"
},
"alias": "이름",
"blueprint": {
"blueprint_to_use": "사용할 블루프린트",
"header": "블루프린트",
"inputs": "입력",
"manage_blueprints": "블루프린트 관리",
"no_blueprints": "블루프린트가 존재하지 않습니다",
"no_inputs": "이 블루프린트에는 입력이 없습니다."
},
"conditions": {
"add": "조건 추가",
"delete": "삭제",
@@ -1268,6 +1286,39 @@
"show_info_automation": "자동화에 대한 정보 표시"
}
},
"blueprint": {
"add": {
"error_no_url": "블루프린트의 URL 을 입력해주세요.",
"file_name": "로컬 블루프린트 파일 이름",
"header": "새로운 블루프린트 추가",
"import_btn": "블루프린트 가져오기",
"import_header": "\"{name}\" (유형: {domain}) 가져오기",
"import_introduction": "Github 및 커뮤니티 포럼에서 다른 사용자의 블루프린트를 가져올 수 있습니다. 블루프린트의 URL 을 하단의 입력란에 입력해주세요.",
"importing": "블루프린트를 가져오는 중 ...",
"raw_blueprint": "블루프린트 내용",
"save_btn": "블루프린트 저장하기",
"saving": "블루프린트 저장 중 ...",
"unsupported_blueprint": "이 블루프린트는 지원되지 않습니다.",
"url": "블루프린트의 URL"
},
"caption": "블루프린트",
"description": "블루프린트를 관리합니다",
"overview": {
"add_blueprint": "블루프린트 가져오기",
"confirm_delete_header": "이 블루프린트를 삭제하시겠습니까?",
"confirm_delete_text": "이 블루프린트를 삭제하시겠습니까?",
"delete_blueprint": "블루프린트 삭제",
"header": "블루프린트 편집기",
"headers": {
"domain": "도메인",
"file_name": "파일 이름",
"name": "이름"
},
"introduction": "블루프린트 편집기를 사용하면 블루프린트를 만들고 편집할 수 있습니다.",
"learn_more": "블루프린트에 대해 더 알아보기",
"use_blueprint": "자동화 만들기"
}
},
"cloud": {
"account": {
"alexa": {
@@ -1572,6 +1623,7 @@
},
"header": "구성요소",
"headers": {
"area": "영역",
"entity_id": "구성요소 ID",
"integration": "통합 구성요소",
"name": "이름",
@@ -2174,18 +2226,23 @@
"system_generated_users_not_editable": "시스템 자동 생성 사용자는 업데이트할 수 없습니다.",
"system_generated_users_not_removable": "시스템 자동 생성 사용자는 제거할 수 없습니다.",
"unnamed_user": "이름이 없는 사용자",
"update_user": "업데이트"
"update_user": "업데이트",
"username": "사용자 이름"
},
"picker": {
"headers": {
"group": "그룹",
"is_active": "활성화",
"is_owner": "소유자",
"name": "이름",
"system": "시스템"
"system": "시스템",
"username": "사용자 이름"
}
},
"users_privileges_note": "사용자 그룹 기능은 현재 작업 중이며, 사용자는 UI 를 통해 인스턴스를 관리할 수 없습니다. 모든 사용자 관리 API 엔드포인트가 관리자에 대한 액세스를 올바르게 제한하는지를 확인하는 중입니다."
},
"zha": {
"add_device": "기기 추가",
"add_device_page": {
"discovered_text": "기기가 발견되면 여기에 표시됩니다.",
"discovery_text": "발견된 기기가 여기에 표시됩니다. 기기의 설명서를 참고하여 기기를 페어링 모드로 설정해주세요.",
@@ -2231,6 +2288,16 @@
"value": "값"
},
"description": "Zigbee Home Automation 네트워크를 관리합니다",
"device_pairing_card": {
"CONFIGURED": "구성이 완료되었습니다",
"CONFIGURED_status_text": "초기화 중",
"INITIALIZED": "초기화가 완료되었습니다",
"INITIALIZED_status_text": "기기를 사용할 준비가 되었습니다",
"INTERVIEW_COMPLETE": "인터뷰가 완료되었습니다",
"INTERVIEW_COMPLETE_status_text": "구성 중",
"PAIRED": "기기가 발견되었습니다",
"PAIRED_status_text": "인터뷰 시작 중"
},
"devices": {
"header": "Zigbee Home Automation - 기기"
},
@@ -2246,6 +2313,7 @@
"unbind_button_label": "그룹 바인딩 해제"
},
"groups": {
"add_group": "그룹 추가",
"add_members": "구성 기기 추가",
"adding_members": "구성 기기 추가",
"caption": "그룹",
@@ -2288,7 +2356,11 @@
"hint_wakeup": "Xiaomi 센서와 같은 일부 기기는 상호 작용하는 동안 기기의 절전 모드 해제가 가능한 약 5초 동안 누를 수 있는 절전 해제 버튼이 있습니다.",
"introduction": "단일 기기에 영향을 주는 ZHA 명령을 실행합니다. 사용 가능한 명령 목록을 보려면 기기를 선택해주세요."
},
"title": "Zigbee Home Automation"
"title": "Zigbee Home Automation",
"visualization": {
"caption": "시각화",
"header": "네트워크 시각화"
}
},
"zone": {
"add_zone": "지역 추가",
@@ -2457,6 +2529,8 @@
"filter_attributes": "속성 필터",
"filter_entities": "구성요소 필터",
"filter_states": "상태 필터",
"last_changed": "최근 변경 됨",
"last_updated": "최근 업데이트 됨",
"more_info": "정보 더보기",
"no_entities": "구성요소가 없습니다",
"set_state": "상태 설정",
@@ -2706,7 +2780,8 @@
},
"picture-glance": {
"description": "그림 한눈에 보기 카드는 이미지와 해당 구성요소의 상태가 아이콘으로 표시됩니다. 오른쪽의 구성요소는 토글 작업을 허용하고 다른 구성요소는 추가 정보 대화상자를 표시합니다.",
"name": "그림 한눈에 보기"
"name": "그림 한눈에 보기",
"state_entity": "상태 구성요소"
},
"picture": {
"description": "그림 카드를 사용하면 인터페이스의 다양한 경로를 탐색하거나 서비스를 호출하는 데 사용할 이미지를 설정할 수 있습니다.",

View File

@@ -7,6 +7,7 @@
}
},
"groups": {
"owner": "Besëtzer",
"system-admin": "Administrateuren",
"system-read-only": "Benotzer mat nëmmen Lies Rechter",
"system-users": "Benotzer"
@@ -547,6 +548,11 @@
"clear": "Läschen",
"show_areas": "Beräicher uweisen"
},
"blueprint-picker": {
"add_user": "Benotzer erstellen",
"remove_user": "Benotzer läschen",
"select_blueprint": "Plang auswielen"
},
"data-table": {
"no-data": "Keng Donnée",
"search": "Sichen"
@@ -716,6 +722,7 @@
"enabled_cause": "Desaktivéiert duerch {cause}.",
"enabled_description": "Deaktivéiert Entitéiten ginn net am Home Assistant bäigesat.",
"enabled_label": "Entitéit aktivéieren",
"enabled_restart_confirm": "Start Home Assistant nei fir dës Entitéiten z'aktivéieren",
"entity_id": "ID vun der Entitéit",
"icon": "Ikon",
"icon_error": "Ikonen sollten am format 'prefix:numm' sinn, Beispill: 'mdi:home'",
@@ -788,6 +795,11 @@
},
"more_info_control": {
"controls": "Kontrollen",
"cover": {
"close_cover": "Paart zoumaachen",
"open_cover": "Paart opmaachen",
"open_tilt_cover": "Paart op Kipp stelle"
},
"details": "Detailler",
"dismiss": "Dialog ofbriechen",
"edit": "Entitéit änneren",
@@ -851,6 +863,29 @@
},
"quick-bar": {
"commands": {
"navigation": {
"areas": "Beräicher",
"automation": "Automatisme",
"blueprint": "Pläng",
"core": "Generell",
"customize": "Personaliséierungen",
"devices": "Apparate",
"entities": "Entitéite",
"helpers": "Helfer",
"info": "Info",
"integrations": "Integratioune",
"logs": "Logs",
"lovelace": "Lovelace Tableau de Bord",
"navigate_to": "Navigéieren zu {panel}",
"navigate_to_config": "Navigéieren zu {panel} Konfiguratioun",
"person": "Persoune",
"scene": "Zeene",
"script": "Skripte",
"server_control": "Server Kontrolle",
"tags": "Tags",
"users": "Benotzer",
"zone": "Zone"
},
"reload": {
"automation": "Automatisme frësch lueden",
"command_line": "Kommando Zeilen Entitéite frësch lueden",
@@ -993,6 +1028,20 @@
"automation": {
"caption": "Automatismen",
"description": "Automatismen verwalten",
"dialog_new": {
"blueprint": {
"use_blueprint": "Plang benotzen"
},
"header": "Nei Automatisme erstellen",
"how": "Wéi wëlls du deng nei Automatisme erstellen?",
"start_empty": "Mat enger eideler Automatisme ufänken",
"thingtalk": {
"create": "Erstellen",
"header": "Beschréif den Automatisme deen soll erstallt ginn",
"input_label": "Wat soll dësen Automatisme maachen?",
"intro": "A mir probéieren et fir dech z'erstellen. Zum Beispill: Schalt Luuchten aus wann ech fort ginn."
}
},
"editor": {
"actions": {
"add": "Aktioun dobäisetzen",
@@ -1073,6 +1122,14 @@
"unsupported_action": "Keng UI Ënnerstëtzung fir Aktioun: {action}"
},
"alias": "Numm",
"blueprint": {
"blueprint_to_use": "Plang fir ze benotzen",
"header": "Plang",
"inputs": "Agab",
"manage_blueprints": "Pläng verwalten",
"no_blueprints": "Du hues kee Plang",
"no_inputs": "Dëse Plang huet keng Agab."
},
"conditions": {
"add": "Konditioun dobäisetzen",
"delete": "Läschen",
@@ -1315,6 +1372,39 @@
}
}
},
"blueprint": {
"add": {
"error_no_url": "Gëff d'URL vum Plang un.",
"file_name": "Lokal Plang Datei Numm",
"header": "Neie Plang erstellen",
"import_btn": "Plang importéieren",
"import_header": "Import \"{name}\" (typ: {domain})",
"import_introduction": "Du kanns Pl¨ng vun aaner Github Benotzer an Community Forumer importéieren. Gëff d'URL vum Plang an.",
"importing": "Plang gëtt importéiert...",
"raw_blueprint": "Plang Inhalt",
"save_btn": "Plang späicheren",
"saving": "Plang gëtt gespäichert...",
"unsupported_blueprint": "Dëse Plang gëtt net ënnerstëtzt",
"url": "URL vum Plang"
},
"caption": "Pläng",
"description": "Pläng verwalten",
"overview": {
"add_blueprint": "Plang importéieren",
"confirm_delete_header": "Dëse Plang läschen?",
"confirm_delete_text": "Sécher fir dëse Plang ze läsche?",
"delete_blueprint": "Plang läschen",
"header": "Plang Editeur",
"headers": {
"domain": "Domain",
"file_name": "Datei Numm",
"name": "Numm"
},
"introduction": "De Plang Editeur erlabt et Pläng z'erstellen an ze veränneren.",
"learn_more": "Méi iwwert Plèang léieren",
"use_blueprint": "Automatisme erstellen"
}
},
"cloud": {
"account": {
"alexa": {
@@ -1628,6 +1718,7 @@
},
"header": "Entitéiten",
"headers": {
"area": "Beräich",
"entity_id": "ID vun der Entitéit",
"integration": "Integratioun",
"name": "Numm",
@@ -1689,6 +1780,8 @@
"info": {
"built_using": "Erstallt mat",
"caption": "Info",
"copy_github": "Fir Github",
"copy_raw": "Rengen Text",
"custom_uis": "Personaliséierte Benotzer Interface:",
"description": "Informatioune zu denger Home Assistant Installation uweisen",
"developed_by": "Entwéckelt vun enger ganzer Rei fantastesche Leit.",
@@ -2152,6 +2245,8 @@
},
"picker": {
"add_script": "Neie Skript erstellen",
"duplicate": "Duplizéieren",
"duplicate_script": "Skript duplizéieren",
"edit_script": "Skript änneren",
"header": "Skript Editeur",
"headers": {
@@ -2283,18 +2378,24 @@
"system_generated_users_not_editable": "Net méiglech System generéiert Benotzer z'aktualiséieren.",
"system_generated_users_not_removable": "Ka keng System generéiert Benotzer läschen.",
"unnamed_user": "Benotzer ouni Numm",
"update_user": "Aktualiséieren"
"update_user": "Aktualiséieren",
"username": "Benotzernumm"
},
"picker": {
"add_user": "Benotzer erstellen",
"headers": {
"group": "Grupp",
"is_active": "Aktiv",
"is_owner": "Besëtzer",
"name": "Numm",
"system": "System"
"system": "System",
"username": "Benotzernumm"
}
},
"users_privileges_note": "Benotzer Gruppp ass nach \"Work in progress\". De Benotzer kann d'Instanz net via UI verwalten. MIr sin mat engem Audit am gaang vun all Management API Endpunkt fir sécher ze stellen dass déi den accès richteg op Administrateuren limitéieren."
},
"zha": {
"add_device": "Apparat dobäisetzen",
"add_device_page": {
"discovered_text": "Apparater tauchen hei op soubaal se entdeckt sinn.",
"discovery_text": "Entdeckten Apparater tauchen op dëser Platz op. Suivéiert d'Instruktiounen fir är Apparater an aktivéiert den Kupplung's Mod.",
@@ -2340,6 +2441,16 @@
"value": "Wäert"
},
"description": "Gestioun vum Zigbee Home Automation Reseau",
"device_pairing_card": {
"CONFIGURED": "Konfiguratioun fäerdeg",
"CONFIGURED_status_text": "Initialiséiert",
"INITIALIZED": "Initialiséierung fäerdeg",
"INITIALIZED_status_text": "Den Apparat ass prett fir ze benotzen",
"INTERVIEW_COMPLETE": "Interview fäerdeg",
"INTERVIEW_COMPLETE_status_text": "Konfiguréiert",
"PAIRED": "Apparat fonnt",
"PAIRED_status_text": "Interview fänkt un"
},
"devices": {
"header": "Zigbee Haus Automatismen - Apparat"
},
@@ -2355,6 +2466,7 @@
"unbind_button_label": "Grupp opléisen"
},
"groups": {
"add_group": "Grupp dobäisetzen",
"add_members": "Membere bäisetzen",
"adding_members": "Membere gi bäigesat",
"caption": "Gruppe",
@@ -2397,7 +2509,11 @@
"hint_wakeup": "Verschidden Apparater wéi Xiaomi Sensoren hunn ee klenge Knäppchen deen een an Intervalle vu ~5s drécke ka fir dass den Apparat un bléift wärend der Interaktioun.",
"introduction": "ZHA Kommandoe ausféieren déi nëmmen een Apparat betreffen. Wielt een Apparat aus fir seng Lëscht vun verfügbare Kommandoe ze gesinn."
},
"title": "Zigbee Haus Automatismen"
"title": "Zigbee Haus Automatismen",
"visualization": {
"caption": "Visualisatioun",
"header": "Visualisatioun vum Netzwierk"
}
},
"zone": {
"add_zone": "Zon dobäisetzen",
@@ -2566,6 +2682,8 @@
"filter_attributes": "Attributer filteren",
"filter_entities": "Entitéite filteren",
"filter_states": "Zoustänn filteren",
"last_changed": "Läscht Ännerung",
"last_updated": "Läscht Aktualiséierung",
"more_info": "Méi Info",
"no_entities": "Keng Entitéiten",
"set_state": "Zoustand setzen",
@@ -2817,6 +2935,10 @@
"description": "Luucht Kaart erlaabt et d'Hellegkeet vun de Luuchten ze veränneren.",
"name": "Luucht"
},
"logbook": {
"description": "Logbuch weist eng Lëscht vun Evenementer vun Entitéiten un.",
"name": "Logbuch"
},
"map": {
"dark_mode": "Däischteren Modus",
"default_zoom": "Standard Zoom",
@@ -2895,6 +3017,9 @@
"edit": "Änneren",
"none": "Keen"
},
"edit_badges": {
"panel_mode": "Dës Badge gi net ugewise well dës Usiicht am \"Panel Modus\" ass."
},
"edit_card": {
"add": "Kaart dobäisetzen",
"clear": "Läschen",
@@ -2939,6 +3064,7 @@
},
"header": "UI änneren",
"header-footer": {
"choose_header_footer": "{typ} auswielen",
"footer": "Fousszeilen",
"header": "Entête",
"types": {
@@ -2947,6 +3073,9 @@
},
"graph": {
"name": "Graph"
},
"picture": {
"name": "Bild"
}
}
},
@@ -2997,7 +3126,8 @@
"sub-element-editor": {
"types": {
"footer": "Fousszeilen Editeur",
"header": "Entête Editeur"
"header": "Entête Editeur",
"row": "Editeur vun der Réih vun Entitéiten"
}
},
"suggest_card": {

View File

@@ -2,11 +2,13 @@
"config_entry": {
"disabled_by": {
"config_entry": "Konfigurer oppføring",
"device": "Enhet",
"integration": "Integrasjon",
"user": "Bruker"
}
},
"groups": {
"owner": "Eier",
"system-admin": "Administratorer",
"system-read-only": "Brukere med lesetilgang",
"system-users": "Brukere"
@@ -298,7 +300,7 @@
"on": "På"
},
"timer": {
"active": "aktiv",
"active": "Aktiv",
"idle": "Inaktiv",
"paused": "pauset"
},
@@ -709,6 +711,16 @@
"service-picker": {
"service": "Tjeneste"
},
"target-picker": {
"add_area_id": "Velg område",
"add_device_id": "Velg enhet",
"add_entity_id": "Velg entitet",
"expand_area_id": "Utvid dette området med de separate enhetene og entitetene det inneholder. Etter utvidelse vil den ikke oppdatere enhetene og entitetene når området endres.",
"expand_device_id": "Utvid denne enheten i separate entiteter. Etter utvidelse vil den ikke oppdatere entitetene når enheten endres.",
"remove_area_id": "Fjern område",
"remove_device_id": "Fjern enhet",
"remove_entity_id": "Fjern entitet"
},
"user-picker": {
"add_user": "Legg til bruker",
"no_user": "Ingen bruker",
@@ -732,6 +744,7 @@
"editor": {
"confirm_delete": "Er du sikker på at du vil slette denne oppføringen?",
"delete": "Slett",
"device_disabled": "Enheten til denne enhtiteen er deaktivert",
"enabled_cause": "Deaktivert av {cause}.",
"enabled_delay_confirm": "De aktiverte enhetene blir lagt til i Home Assistant om {delay} sekunder",
"enabled_description": "Deaktiverte entiteter vil ikke bli lagt til i Home Assistant.",
@@ -742,6 +755,7 @@
"icon_error": "Ikoner bør være i formatet 'prefiks:ikonnavn', f.eks 'mdi:home'",
"name": "Navn",
"note": "Merk: Dette fungerer kanskje ikke ennå med alle integrasjoner.",
"open_device_settings": "Åpne enhetsinnstillinger",
"unavailable": "Denne entiteten er ikke tilgjengelig for øyeblikket.",
"update": "Oppdater"
},
@@ -1666,6 +1680,7 @@
"unknown_condition": "Ukjent tilstand"
},
"create": "Lag automasjon med enheten",
"create_disable": "Kan ikke opprette automasjon med deaktivert enhet",
"no_automations": "Ingen automasjoner",
"no_device_automations": "Det er ingen automasjoner tilgjengelig for denne enheten.",
"triggers": {
@@ -1694,6 +1709,15 @@
"description": "Administrer tilkoblede enheter",
"device_info": "Enhetsinformasjon",
"device_not_found": "Enhet ikke funnet",
"disabled": "Deaktivert",
"disabled_by": {
"config_entry": "Konfigurer oppføring",
"integration": "Integrasjon",
"user": "Bruker"
},
"enabled_cause": "Enheten er deaktivert av {cause}",
"enabled_description": "Deaktiverte enheter vises ikke, og entiteter som tilhører enheten deaktiveres og ikke legges til i Home Assistant",
"enabled_label": "Aktivér enhet",
"entities": {
"add_entities_lovelace": "Legg til i Lovelace",
"disabled_entities": "+{count} {count, plural,\n one {deaktivert entitet}\n other {deaktiverte entiteter}\n}",
@@ -1703,14 +1727,25 @@
},
"name": "Navn",
"no_devices": "Ingen enheter",
"picker": {
"filter": {
"filter": "Filter",
"hidden_devices": "{number} {number, plural,\n one {skjult enhet}\n other {skjulte enheter}\n}",
"show_all": "Vis alle",
"show_disabled": "Vis deaktiverte enheter"
},
"search": "Søk etter enheter"
},
"scene": {
"create": "Lag scene med enheten",
"create_disable": "Kan ikke opprette scene med deaktivert enhet",
"no_scenes": "Ingen scener",
"scenes": "Scener"
},
"scenes": "Scener",
"script": {
"create": "Lag skript med enheten",
"create_disable": "Kan ikke opprette skript med deaktivert enhet",
"no_scripts": "Ingen skript",
"scripts": "Skript"
},
@@ -1743,6 +1778,7 @@
},
"header": "Entiteter",
"headers": {
"area": "Område",
"entity_id": "Entitets-ID",
"integration": "Integrasjon",
"name": "Navn",
@@ -2391,6 +2427,7 @@
"editor": {
"activate_user": "Aktiver bruker",
"active": "Aktiv",
"active_tooltip": "Kontrollerer om brukeren kan logge inn",
"admin": "",
"caption": "Vis bruker",
"change_password": "Endre passord",
@@ -2399,7 +2436,7 @@
"delete_user": "Slett bruker",
"group": "Gruppe",
"id": "Id",
"name": "Navn",
"name": "Visningsnavn",
"new_password": "Nytt passord",
"owner": "Eier",
"password_changed": "Passordet ble endret",
@@ -2407,14 +2444,18 @@
"system_generated_users_not_editable": "Kan ikke oppdatere systemopprettede brukere.",
"system_generated_users_not_removable": "Kan ikke fjerne systemopprettede brukere.",
"unnamed_user": "Bruker uten navn",
"update_user": "Oppdater"
"update_user": "Oppdater",
"username": "Brukernavn"
},
"picker": {
"add_user": "Legg til bruker",
"headers": {
"group": "Gruppe",
"name": "Navn",
"system": ""
"is_active": "Aktiv",
"is_owner": "Eier",
"name": "Visningsnavn",
"system": "System generert",
"username": "Brukernavn"
}
},
"users_privileges_note": "Brukergruppefunksjonen er et pågående arbeid. Brukeren vil ikke kunne administrere forekomsten via brukergrensesnittet. Vi overvåker fortsatt alle administrasjons-API-endepunkter for å sikre at de begrenser tilgangen til administratorer på riktig måte."
@@ -2466,6 +2507,16 @@
"value": "Verdi"
},
"description": "ZigBee Hjemmeautomasjon nettverksadministrasjon",
"device_pairing_card": {
"CONFIGURED": "Konfigurasjonen er fullført",
"CONFIGURED_status_text": "Initialiserer",
"INITIALIZED": "Initialiseringen er fullført",
"INITIALIZED_status_text": "Enheten er klar til bruk",
"INTERVIEW_COMPLETE": "Intervju fullført",
"INTERVIEW_COMPLETE_status_text": "Konfigurerer",
"PAIRED": "Enhet funnet",
"PAIRED_status_text": "Starter intervju"
},
"devices": {
"header": "ZigBee Hjemmeautomasjon - Enhet"
},
@@ -2973,20 +3024,20 @@
"name": "Mediekontroll"
},
"picture-elements": {
"description": "Picture Elements-kortet er en av de mest allsidige korttyper. Kortene lar deg plassere ikoner eller tekst og til og med tjenester! På et bilde basert på koordinater.",
"description": "Bildeelementer-kortet er et av de mest allsidige korttypene. Kortene lar deg plassere ikoner eller tekst og til og med tjenester! På et bilde basert på koordinater.",
"name": "Bildeelementer"
},
"picture-entity": {
"description": "Bilde entitet kortet viser en entitet i form av et bilde. I stedet for bilder fra URL, kan det også vise bilde av kameraentiteter.",
"name": "Bildeoppføring"
"name": "Bilde entitet"
},
"picture-glance": {
"description": "Picture Glance-kortet viser et bilde og tilhørende entitetstilstander som et ikon. Entitetene på høyre side tillater veksling av handlinger, andre viser dialogboksen mer informasjon.",
"description": "Bilde blikk-kortet viser et bilde og tilhørende entitetstilstander som et ikon. Entitetene på høyre side tillater veksling av handlinger, andre viser dialogboksen mer informasjon.",
"name": "Bilde blikk",
"state_entity": "Statusentitet"
},
"picture": {
"description": "Bildekortet lar deg stille inn et bilde som skal brukes til navigasjon til forskjellige baner i grensesnittet ditt eller for å tilkalle en tjeneste.",
"description": "Bildekortet lar deg sette inn et bilde som skal brukes til navigasjon til forskjellige baner i grensesnittet ditt eller for å tilkalle en tjeneste.",
"name": "Bilde"
},
"plant-status": {
@@ -3395,10 +3446,13 @@
"change_password": {
"confirm_new_password": "Bekreft nytt passord",
"current_password": "Nåværende passord",
"error_new_is_old": "Nytt passord må være annerledes enn gjeldende passord",
"error_new_mismatch": "Oppgitte nye passordverdier stemmer ikke overens",
"error_required": "Nødvendig",
"header": "Endre passord",
"new_password": "Nytt passord",
"submit": "Send inn"
"submit": "Send inn",
"success": "Passordet ble endret"
},
"current_user": "Du er logget inn som {fullName}.",
"customize_sidebar": {
@@ -3419,7 +3473,7 @@
"description": "Dette vil skjule sidepanelet som standard, tilsvarende opplevelsen på en mobil.",
"header": "Skjul alltid sidepanelet"
},
"is_owner": "Du er en eier.",
"is_owner": "Du er en eier",
"language": {
"dropdown_label": "Språk",
"header": "Språk",

View File

@@ -2,11 +2,13 @@
"config_entry": {
"disabled_by": {
"config_entry": "Configuratie-item",
"device": "Apparaat",
"integration": "Integratie",
"user": "Gebruiker"
}
},
"groups": {
"owner": "Eigenaar",
"system-admin": "Beheerders",
"system-read-only": "Alleen-lezen gebruikers",
"system-users": "Gebruikers"
@@ -709,6 +711,16 @@
"service-picker": {
"service": "Service"
},
"target-picker": {
"add_area_id": "Kies gebied",
"add_device_id": "Kies apparaat",
"add_entity_id": "Kies entiteit",
"expand_area_id": "Breid dit gebied uit in de afzonderlijke apparaten en entiteiten die het bevat. Na het uitbreiden zal het de apparaten en entiteiten niet bijwerken wanneer het gebied verandert.",
"expand_device_id": "Breid dit apparaat uit in afzonderlijke entiteiten. Na het uitbreiden worden de entiteiten niet bijgewerkt wanneer het apparaat verandert.",
"remove_area_id": "Verwijder gebied",
"remove_device_id": "Verwijder apparaat",
"remove_entity_id": "Verwijder entiteit"
},
"user-picker": {
"add_user": "Gebruiker toevoegen",
"no_user": "Geen gebruiker",
@@ -732,6 +744,7 @@
"editor": {
"confirm_delete": "Weet je zeker dat je dit item wilt verwijderen?",
"delete": "Verwijderen",
"device_disabled": "Het apparaat van deze entiteit is uitgeschakeld.",
"enabled_cause": "Uitgeschakeld vanwege {cause}",
"enabled_delay_confirm": "De ingeschakelde entiteiten worden over {delay} seconden aan Home Assistant toegevoegd",
"enabled_description": "Uitgeschakelde entiteiten zullen niet aan Home Assistant worden toegevoegd",
@@ -742,6 +755,7 @@
"icon_error": "Pictogrammen moeten de notatie 'prefix:pictogramnaam' hebben, bijvoorbeeld 'mdi:home'",
"name": "Naam",
"note": "Opmerking: dit werkt mogelijk nog niet met alle integraties.",
"open_device_settings": "Open de apparaatinstellingen",
"unavailable": "Deze entiteit is momenteel niet beschikbaar.",
"update": "Bijwerken"
},
@@ -1028,7 +1042,7 @@
"confirmation_text": "Alle apparaten in dit gebied zullen niet meer toegewezen zijn.",
"confirmation_title": "Weet je zeker dat je dit gebied wilt verwijderen?"
},
"description": "Overzicht van alle gebieden in je huis.",
"description": "Groepeer apparaten in gebieden",
"editor": {
"area_id": "Gebieds-ID",
"create": "Aanmaken",
@@ -1050,7 +1064,7 @@
},
"automation": {
"caption": "Automatiseringen",
"description": "Het maken en bewerken van automatiseringen",
"description": "Maak aangepaste gedragsregels voor uw huis",
"dialog_new": {
"blueprint": {
"use_blueprint": "Gebruik een blauwdruk"
@@ -1400,7 +1414,7 @@
"error_no_url": "Voer de URL van de blauwdruk in.",
"header": "Voeg een nieuwe blauwdruk toe",
"import_btn": "Blauwdruk importeren",
"import_header": "Importeer {name} ( {domain} )",
"import_header": "Importeer \"{name}\" (type: {domain})",
"import_introduction": "U kunt blauwdrukken van andere gebruikers importeren vanuit Github en de communityforums. Voer de URL van de blauwdruk hieronder in.",
"importing": "Blauwdruk importeren ...",
"save_btn": "Bewaar blauwdruk",
@@ -1410,14 +1424,18 @@
"caption": "Blauwdrukken",
"description": "Beheer blauwdrukken",
"overview": {
"add_blueprint": "Blauwdruk importeren",
"confirm_delete_header": "Deze blauwdruk verwijderen?",
"confirm_delete_text": "Weet je zeker dat je deze blauwdruk wilt verwijderen?",
"header": "Blauwdrukeditor",
"headers": {
"domain": "Domein",
"file_name": "Bestandsnaam",
"name": "Naam"
},
"introduction": "Met de blauwdrukeditor kunt je blauwdrukken maken en bewerken.",
"learn_more": "Meer informatie over blauwdrukken"
"learn_more": "Meer informatie over blauwdrukken",
"use_blueprint": "Automatisering maken"
}
},
"cloud": {
@@ -1500,7 +1518,7 @@
"title": "Alexa"
},
"caption": "Home Assistent Cloud",
"description_features": "Bestuur weg van huis, verbind met Alexa en Google Assistant.",
"description_features": "Bedien uw huis wanneer u weg bent en integreer met Alexa en Google Assistant",
"description_login": "Ingelogd als {email}",
"description_not_login": "Niet ingelogd",
"dialog_certificate": {
@@ -1595,7 +1613,7 @@
},
"core": {
"caption": "Algemeen",
"description": "Wijzig je algemene Home Assistant-configuratie",
"description": "Eenheidssysteem, locatie, tijdzone en andere algemene parameters",
"section": {
"core": {
"core_config": {
@@ -1657,6 +1675,7 @@
"unknown_condition": "Onbekende toestand"
},
"create": "Maak een automatisering aan met het apparaat",
"create_disable": "Kan geen automatisering maken met een uitgeschakeld apparaat",
"no_automations": "Geen automatiseringen",
"no_device_automations": "Er zijn geen automatiseringen beschikbaar voor dit apparaat.",
"triggers": {
@@ -1682,9 +1701,18 @@
"no_devices": "Geen apparaten"
},
"delete": "Verwijderen",
"description": "Beheer verbonden apparaten",
"description": "Beheer geconfigureerde apparaten",
"device_info": "Apparaat info",
"device_not_found": "Apparaat niet gevonden.",
"disabled": "Uitgeschakeld",
"disabled_by": {
"config_entry": "Configuratie-invoer",
"integration": "Integratie",
"user": "Gebruiker"
},
"enabled_cause": "Het apparaat is uitgeschakeld door {cause}.",
"enabled_description": "Uitgeschakelde apparaten worden niet weergegeven en entiteiten die bij het apparaat horen, worden uitgeschakeld en niet toegevoegd aan Home Assistant.",
"enabled_label": "Schakel apparaat in",
"entities": {
"add_entities_lovelace": "Voeg toe aan de Lovelace gebruikersinterface",
"disabled_entities": "+{count} {count, plural,\n one {uitgeschakelde entiteit}\n other {uitgeschakelde entiteiten}\n}",
@@ -1694,14 +1722,25 @@
},
"name": "Naam",
"no_devices": "Geen apparaten",
"picker": {
"filter": {
"filter": "Filter",
"hidden_devices": "{number} verborgen {number, plural,\n one {apparaat}\n other {apparaten}\n}",
"show_all": "Alles weergeven",
"show_disabled": "Toon uitgeschakelde apparaten"
},
"search": "Zoek apparaten"
},
"scene": {
"create": "Maak een scène aan met het apparaat",
"create_disable": "Kan geen scène maken met een uitgeschakeld apparaat",
"no_scenes": "Geen scènes",
"scenes": "Scènes"
},
"scenes": "Scènes",
"script": {
"create": "Maak een script aan met het apparaat",
"create_disable": "Kan geen script maken met een uitgeschakeld apparaat",
"no_scripts": "Geen scripts",
"scripts": "Scripts"
},
@@ -1734,6 +1773,7 @@
},
"header": "Entiteiten",
"headers": {
"area": "Gebied",
"entity_id": "Entiteits-ID",
"integration": "Integratie",
"name": "Naam",
@@ -1798,7 +1838,7 @@
"copy_github": "Voor GitHub",
"copy_raw": "Ruwe tekst",
"custom_uis": "Aangepaste UI's:",
"description": "Informatie over je Home Assistant installatie",
"description": "Versie, systeemstatus en links naar documentatie",
"developed_by": "Ontwikkeld door een stel geweldige mensen.",
"documentation": "Documentatie",
"frontend": "Frontend",
@@ -1864,11 +1904,11 @@
"delete": "Verwijder",
"delete_button": "Verwijder {integration}.",
"delete_confirm": "Weet je zeker dat je deze integratie wilt verwijderen?",
"device_unavailable": "apparaat niet beschikbaar",
"device_unavailable": "Apparaat niet beschikbaar",
"devices": "{count} {count, plural,\n one {apparaat}\n other {apparaten}\n}",
"documentation": "Documentatie",
"entities": "{count} {count, plural,\n one {entiteit}\n other {entiteiten}\n}",
"entity_unavailable": "entiteit niet beschikbaar",
"entity_unavailable": "Entiteit niet beschikbaar",
"firmware": "Firmware: {version}",
"hub": "Verbonden via",
"manuf": "door {manufacturer}",
@@ -1904,7 +1944,7 @@
},
"configure": "Configureer",
"configured": "Geconfigureerd",
"description": "Beheer en installeer integraties",
"description": "Beheer integraties met services, apparaten, ...",
"details": "Integratiedetails",
"discovered": "Ontdekt",
"home_assistant_website": "Home Assistant-website",
@@ -1989,7 +2029,7 @@
"open": "Open"
}
},
"description": "Configureer je Lovelace-dashboards",
"description": "Maak aangepaste cards om uw huis te besturen",
"resources": {
"cant_edit_yaml": "Je gebruikt Lovelace in YAML-modus, daarom kun je je bronnen niet beheren via de gebruikersinterface. Beheer ze in configuration.yaml.",
"caption": "Bronnen",
@@ -2188,7 +2228,7 @@
"scene": {
"activated": "Scène {name} geactiveerd.",
"caption": "Scènes",
"description": "Maak en bewerk scènes",
"description": "Leg apparaatstatussen vast en roep ze later gemakkelijk op",
"editor": {
"default_name": "Nieuwe scène",
"devices": {
@@ -2232,7 +2272,7 @@
},
"script": {
"caption": "Scripts",
"description": "Maak en bewerk scripts",
"description": "Voer een reeks acties uit",
"editor": {
"alias": "Naam",
"default_name": "Nieuw script",
@@ -2343,7 +2383,7 @@
"confirm_remove": "Weet je zeker dat je tag {tag} wilt verwijderen?",
"confirm_remove_title": "Tag verwijderen?",
"create_automation": "Creëer automatisering met tag",
"description": "Beheer tags",
"description": "Activeer automatiseringen wanneer een NFC-tag, QR-code, enz. wordt gescand",
"detail": {
"companion_apps": "bijbehorende apps",
"create": "Creëer",
@@ -2382,6 +2422,7 @@
"editor": {
"activate_user": "Activeer gebruiker",
"active": "Actief",
"active_tooltip": "Bepaal of de gebruiker kan inloggen",
"admin": "Beheerder",
"caption": "Bekijk gebruiker",
"change_password": "Wachtwoord wijzigen",
@@ -2390,7 +2431,7 @@
"delete_user": "Verwijder gebruiker",
"group": "Groep",
"id": "ID",
"name": "Naam",
"name": "Weergavenaam",
"new_password": "Nieuw wachtwoord",
"owner": "Eigenaar",
"password_changed": "Het wachtwoord is gewijzigd!",
@@ -2398,19 +2439,24 @@
"system_generated_users_not_editable": "Kan door het systeem gegenereerde gebruikers niet bijwerken.",
"system_generated_users_not_removable": "Kan door het systeem gegenereerde gebruikers niet verwijderen.",
"unnamed_user": "Naamloze gebruiker",
"update_user": "Bijwerken"
"update_user": "Bijwerken",
"username": "Gebruikersnaam"
},
"picker": {
"add_user": "Gebruiker toevoegen",
"headers": {
"group": "Groep",
"name": "Naam",
"system": "Systeem"
"is_active": "Actief",
"is_owner": "Eigenaar",
"name": "Weergavenaam",
"system": "Systeem gegenereerd",
"username": "Gebruikersnaam"
}
},
"users_privileges_note": "Gebruikersgroepen zijn nog in ontwikkeling. De gebruiker kan de instantie niet beheren via de interface. We controleren nog steeds alle beheer API eindpunten om ervoor te zorgen dat ze de toegang tot beheerders correct beperken."
},
"zha": {
"add_device": "Apparaat toevoegen",
"add_device_page": {
"discovered_text": "Apparaten zullen hier verschijnen zodra ze zijn ontdekt.",
"discovery_text": "Gevonden apparaten worden hier weergegeven. Volg de instructies voor je apparaat of apparaten en plaats het apparaat of de apparaten in de koppelingsmodus.",
@@ -2456,6 +2502,14 @@
"value": "Waarde"
},
"description": "Zigbee Home Automation netwerkbeheer",
"device_pairing_card": {
"CONFIGURED": "Configuratie voltooid",
"CONFIGURED_status_text": "Initialiseren",
"INITIALIZED": "Initialisatie voltooid",
"INITIALIZED_status_text": "Het apparaat is klaar voor gebruik",
"INTERVIEW_COMPLETE_status_text": "Configureren",
"PAIRED": "Apparaat gevonden"
},
"devices": {
"header": "Zigbee Home Automation - Apparaat"
},
@@ -2471,6 +2525,7 @@
"unbind_button_label": "Ontkoppel groep"
},
"groups": {
"add_group": "Groep toevoegen",
"add_members": "Leden toevoegen",
"adding_members": "Leden toevoegen",
"caption": "Groepen",
@@ -2513,7 +2568,11 @@
"hint_wakeup": "Sommige apparaten, zoals Xiaomi-sensoren hebben een wekknop die je met tussenpozen van 5 seconden kunt indrukken om het apparaat wakker te houden terwijl je ermee communiceert",
"introduction": "Voer ZHA-commando's uit die van invloed zijn op een enkel apparaat. Kies een apparaat om een lijst met beschikbare commando's te zien."
},
"title": "Zigbee Home Automation"
"title": "Zigbee Home Automation",
"visualization": {
"caption": "Visualisatie",
"header": "Netwerkvisualisatie"
}
},
"zone": {
"add_zone": "Zone toevoegen",
@@ -2967,7 +3026,8 @@
},
"picture-glance": {
"description": "De Picture Glance-kaart toont een afbeelding en de bijbehorende entiteitstoestanden als een pictogram. De entiteiten aan de rechterkant staan schakelacties toe, andere tonen het dialoogvenster met meer informatie.",
"name": "Afbeelding oogopslag"
"name": "Afbeelding oogopslag",
"state_entity": "Status entiteit"
},
"picture": {
"description": "Met de Picture-kaart kunt u een afbeelding instellen voor navigatie naar verschillende paden in uw interface of om een service te activeren.",
@@ -3178,7 +3238,7 @@
"attribute_not_found": "Kenmerk {attribute} niet beschikbaar in: {entity}",
"entity_non_numeric": "Entiteit is niet-numeriek: {entity}",
"entity_not_found": "Entiteit niet beschikbaar: {entity}",
"entity_unavailable": "{entity} is momenteel niet beschikbaar",
"entity_unavailable": "Entiteit is momenteel niet beschikbaar: {entity}",
"starting": "Home Assistant is aan het opstarten, wellicht is nog niet alles beschikbaar"
}
},
@@ -3379,10 +3439,12 @@
"change_password": {
"confirm_new_password": "Bevestig nieuw wachtwoord",
"current_password": "Huidige wachtwoord",
"error_new_is_old": "Het nieuwe wachtwoord moet anders zijn dan het huidige wachtwoord",
"error_required": "Verplicht",
"header": "Wachtwoord wijzigen",
"new_password": "Nieuw wachtwoord",
"submit": "Verzenden"
"submit": "Verzenden",
"success": "Wachtwoord is succesvol veranderd"
},
"current_user": "Je bent momenteel ingelogd als {fullName}.",
"customize_sidebar": {

View File

@@ -1744,6 +1744,7 @@
},
"header": "Rejestr encji",
"headers": {
"area": "Obszar",
"entity_id": "Identyfikator encji",
"integration": "Integracja",
"name": "Nazwa",
@@ -2471,6 +2472,16 @@
"value": "Wartość"
},
"description": "Zarządzanie siecią Zigbee Home Automation",
"device_pairing_card": {
"CONFIGURED": "Konfigurowanie zakończona",
"CONFIGURED_status_text": "Inicjalizacja",
"INITIALIZED": "Inicjalizacja zakończona",
"INITIALIZED_status_text": "Urządzenie jest gotowe do użycia",
"INTERVIEW_COMPLETE": "Odpytywanie zakończone",
"INTERVIEW_COMPLETE_status_text": "Konfigurowanie",
"PAIRED": "Znaleziono urządzenie",
"PAIRED_status_text": "Rozpoczęcie odpytywania"
},
"devices": {
"header": "Zigbee Home Automation - urządzenie"
},

View File

@@ -7,6 +7,7 @@
}
},
"groups": {
"owner": "Proprietário",
"system-admin": "Administradores",
"system-read-only": "Utilizadores só com permissões de leitura",
"system-users": "Utilizadores"
@@ -547,6 +548,11 @@
"clear": "Limpar",
"show_areas": "Mostrar áreas"
},
"blueprint-picker": {
"add_user": "Adicionar um utilizador",
"remove_user": "Remover utilizador",
"select_blueprint": "Escolhe um projeto"
},
"data-table": {
"no-data": "Dados do evento",
"search": "Procurar"
@@ -732,15 +738,15 @@
"enabled_label": "Ativar entidade",
"enabled_restart_confirm": "Reinicie o Home Assistant para ativar as entidades",
"entity_id": "Identificação da entidade",
"icon": "Substituição do ícone",
"icon": "Ícone",
"icon_error": "Os ícones devem estar no formato 'prefixo:nome do ícone', por exemplo 'mdi:home'.",
"name": "Substituição do nome",
"name": "Nome",
"note": "Nota: isto pode ainda não funcionar com todas as integrações.",
"unavailable": "Esta entidade não está atualmente disponível.",
"update": "Atualizar"
},
"faq": "Documentação",
"no_unique_id": "Esta entidade não tem uma identificação única, portanto suas configurações não podem ser geridas a partir da UI. Para mais informações, ver {faq_link}.",
"no_unique_id": "Esta entidade (\"{entity_id}\") não tem uma identificação única, portanto suas configurações não podem ser geridas a partir da UI. Para mais informações, ver {faq_link}.",
"related": "Relacionadas",
"settings": "Definições"
},
@@ -872,6 +878,7 @@
"navigation": {
"areas": "Áreas",
"automation": "Automação",
"blueprint": "Projecto",
"core": "Geral",
"customize": "Personalização",
"devices": "Dispositivos",
@@ -1041,6 +1048,20 @@
"automation": {
"caption": "Automação",
"description": "Gerir Automações",
"dialog_new": {
"blueprint": {
"use_blueprint": "Utilize o projeto"
},
"header": "Criar uma automatização",
"how": "Como quer criar uma automatização?",
"start_empty": "Começar com uma automatização vazia",
"thingtalk": {
"create": "Criar",
"header": "Descreva a automatização que pretende criar",
"input_label": "O que deve fazer esta automatização?",
"intro": "E nós vamos tentar criar por ti. Por exemplo: Desliga as luzes quando eu sair."
}
},
"editor": {
"actions": {
"add": "Adicionar ação",
@@ -1121,6 +1142,14 @@
"unsupported_action": "Ação não suportada: {action}"
},
"alias": "Nome",
"blueprint": {
"blueprint_to_use": "Projeto a usar",
"header": "Projeto",
"inputs": "Entrada",
"manage_blueprints": "Gerir projetos",
"no_blueprints": "Tu nao tens nenhum projeto",
"no_inputs": "Este projeto não tem nenhuma entrada"
},
"conditions": {
"add": "Acrescentar condição",
"delete": "Apagar",
@@ -1206,7 +1235,7 @@
"edit_ui": "Editar com IU",
"edit_yaml": "Editar como YAML",
"enable_disable": "Habilitar/desabilitar automação",
"introduction": "Crie automações para dar vida à sua casa",
"introduction": "Utilize automações para dar vida à sua casa",
"load_error_not_editable": "Apenas as automações em automations.yaml são editáveis.",
"load_error_unknown": "Erro ao carregar a automação ({err_no}).",
"max": {
@@ -1358,6 +1387,39 @@
}
}
},
"blueprint": {
"add": {
"error_no_url": "Por favor introduza o URL do projeto",
"file_name": "Nome do ficheiro do projeto local",
"header": "Adicionar novo projeto",
"import_btn": "Importar projeto",
"import_header": "Importar \"{name}\" (tipo: {domain})",
"import_introduction": "Você pode importar projetos de outros utilizadores pelo Github e pelo fórum da comunidade. introduza o URL do projeto abaixo",
"importing": "A importar projeto...",
"raw_blueprint": "Conteúdo do projeto",
"save_btn": "Projeto guardado",
"saving": "A guardar projecto...",
"unsupported_blueprint": "Projeto não suportado",
"url": "URL do projeto"
},
"caption": "Projeto",
"description": "Gerir projeto",
"overview": {
"add_blueprint": "Importar projeto",
"confirm_delete_header": "Apagar projeto",
"confirm_delete_text": "Tem a certeza que pretende apagar este projeto?",
"delete_blueprint": "Excluir projeto",
"header": "Editor de projetos",
"headers": {
"domain": "Domínio",
"file_name": "Nome do ficheiro",
"name": "Nome"
},
"introduction": "Este editor de projetos permite criar e editar projetos.",
"learn_more": "Aprenda mais sobre projetos",
"use_blueprint": "Criar automação"
}
},
"cloud": {
"account": {
"alexa": {
@@ -1670,6 +1732,7 @@
},
"header": "Entidades",
"headers": {
"area": "Área",
"entity_id": "ID da Entidade",
"integration": "Integração",
"name": "Nome",
@@ -1682,7 +1745,7 @@
"confirm_partly_text": "Você pode remover apenas {removable} das {selected} entidades selecionadas. As entidades só podem ser removidas quando a integração deixar de suportá-las. Por vezes é necessário reiniciar o Home Assistant antes de poder remover as entidades de uma integração removida. Tem a certeza de que deseja remover as entidades removíveis?",
"confirm_partly_title": "Apenas {number} {number, plural,\n uma {selected entity} pode ser removida \n outras {selected entities} podem ser removidas \n}.",
"confirm_text": "Deve remover da configuração do Lovelace e das automações se contêm estas entidades",
"confirm_title": "Deseja remover {number} entidades?"
"confirm_title": "Deseja remover {number} {number, plural,\n one {entidade}\n other {entidades}\n}?"
},
"search": "Procurar entidades",
"selected": "Selecionou {number}",
@@ -1732,6 +1795,7 @@
"built_using": "Construído com",
"caption": "Informação",
"copy_github": "Para GitHub",
"copy_raw": "Texto simples",
"custom_uis": "IUs personalizados:",
"description": "Ver informações sobre a instalação do Home Assistant",
"developed_by": "Desenvolvido por um punhado de pessoas incríveis.",
@@ -2126,7 +2190,7 @@
"without_device": "Entidades sem dispositivo"
},
"icon": "Ícone",
"introduction": "Crie cenários para dar vida à sua casa.",
"introduction": "Utilize cenários para dar vida à sua casa.",
"load_error_not_editable": "Apenas cenários em scenes.yaml são editáveis.",
"load_error_unknown": "Erro ao carregar cena ({err_no}).",
"name": "Nome",
@@ -2309,7 +2373,7 @@
"delete_user": "Apagar utilizador",
"group": "Grupo",
"id": "ID",
"name": "Nome",
"name": "Nome em Exibição",
"new_password": "Nova senha",
"owner": "Proprietário",
"password_changed": "A senha foi alterada com sucesso",
@@ -2317,19 +2381,24 @@
"system_generated_users_not_editable": "Não foi possível atualizar os utilizadores gerados pelo sistema.",
"system_generated_users_not_removable": "Não é possível remover utilizadores gerados pelo sistema.",
"unnamed_user": "Utilizador sem nome",
"update_user": "Atualizar"
"update_user": "Atualizar",
"username": "Nome de Utilizador"
},
"picker": {
"add_user": "Adicionar Utilizador",
"headers": {
"group": "Grupo",
"name": "Nome",
"system": "Sistema"
"is_active": "Ativo",
"is_owner": "Proprietário",
"name": "Nome em Exibição",
"system": "Gerado pelo sistema",
"username": "Nome de Utilizador"
}
},
"users_privileges_note": "O grupo de utilizadores é um trabalho em progresso. O utilizador não poderá administrar a instância por meio da interface de utilizador. Ainda estamos a auditar todos os endpoints da API de gestão para garantir que eles limitam corretamente o acesso aos administradores."
},
"zha": {
"add_device": "Adicionar Dispositivo",
"add_device_page": {
"discovered_text": "Os dispositivos aparecem aqui uma vez descobertos.",
"discovery_text": "Os dispositivos descobertos aparecerão aqui. Siga as instruções para o(s) seu(s) dispositivo(s) e coloque o(s) dispositivo(s) em modo de emparelhamento.",
@@ -2375,6 +2444,16 @@
"value": "Valor"
},
"description": "Gestão de rede Zigbee Home Automation",
"device_pairing_card": {
"CONFIGURED": "Configuração Completa",
"CONFIGURED_status_text": "A inicializar",
"INITIALIZED": "Inicialização completa",
"INITIALIZED_status_text": "O dispositivo está pronto para uso",
"INTERVIEW_COMPLETE": "Entrevista Completa",
"INTERVIEW_COMPLETE_status_text": "Configurando",
"PAIRED": "Dispositivo encontrado",
"PAIRED_status_text": "A iniciar entrevista"
},
"devices": {
"header": "Zigbee Home Automation - Dispositivo"
},
@@ -2390,6 +2469,7 @@
"unbind_button_label": "Desvincular grupo"
},
"groups": {
"add_group": "Adicionar grupo",
"add_members": "Adicionar membros",
"adding_members": "A Adicionar membros",
"caption": "Grupos",
@@ -2432,7 +2512,11 @@
"hint_wakeup": "Alguns dispositivos, como os sensores Xiaomi, têm um botão de ativação que você pode pressionar em intervalos de ~ 5 segundos para manter os dispositivos acordados enquanto você interage com eles.",
"introduction": "Execute comandos ZHA que afetem um único dispositivo. Escolha um dispositivo para ver uma lista de comandos disponíveis."
},
"title": "Automação residencial zigbee"
"title": "Automação residencial zigbee",
"visualization": {
"caption": "Visualização",
"header": "Visualização de rede"
}
},
"zone": {
"add_zone": "Adicionar zona",
@@ -2622,6 +2706,7 @@
"reset": "Redefinir para modelo de demonstração",
"result_type": "Tipo de resultado",
"template_extensions": "Extensões de templates do Home Assistant",
"time": "Este modelo atualiza ao início de cada minuto",
"title": "Template",
"unknown_error_template": "Erro desconhecido ao processar o template"
}
@@ -2688,7 +2773,7 @@
}
},
"changed_toast": {
"message": "A configuração do Lovelace foi atualizada para este painel, gostaria de atualizar?",
"message": "A configuração do Lovelace foi atualizada para este painel, gostaria de atualizar para verificar as alterações?",
"refresh": "Atualizar"
},
"editor": {
@@ -2852,6 +2937,10 @@
"description": "O cartão Luz permite alterar o brilho da luz.",
"name": "Luz"
},
"logbook": {
"description": "O cartão dos registos mostra a lista de eventos para as entidades",
"name": "Registos"
},
"map": {
"dark_mode": "Modo escuro?",
"default_zoom": "Zoom padrão",
@@ -2880,7 +2969,8 @@
},
"picture-glance": {
"description": "O cartão Vista de imagem mostra uma imagem e os estados das entidades correspondentes como um ícone. As entidades do lado direito permitem alternar ações, outras mostram a opção mais informações.",
"name": "Vista sobre imagem"
"name": "Vista sobre imagem",
"state_entity": "Estado da entidade"
},
"picture": {
"description": "O cartão de imagem permite definir uma imagem a ser usada para navegação em vários pontos na sua interface ou para chamar um serviço.",

View File

@@ -1,7 +1,8 @@
{
"config_entry": {
"disabled_by": {
"config_entry": "Запись",
"config_entry": "Конфигурация",
"device": "Устройство",
"integration": "Интеграция",
"user": "Пользователь"
}
@@ -394,7 +395,7 @@
},
"cover": {
"position": "Положение",
"tilt_position": "Положение наклона"
"tilt_position": "Наклон"
},
"fan": {
"direction": "Направление",
@@ -550,7 +551,8 @@
},
"blueprint-picker": {
"add_user": "Добавить пользователя",
"remove_user": "Удалить пользователя"
"remove_user": "Удалить пользователя",
"select_blueprint": "Выберите проект"
},
"data-table": {
"no-data": "Нет данных",
@@ -709,6 +711,16 @@
"service-picker": {
"service": "Служба"
},
"target-picker": {
"add_area_id": "Выбрать помещение",
"add_device_id": "Выбрать устройство",
"add_entity_id": "Выбрать объект",
"expand_area_id": "Разделить это помещение на отдельные устройства и объекты. После разделения устройства и объекты не будут обновляться при изменении помещения.",
"expand_device_id": "Разделить это устройство на отдельные объекты. После разделения объекты не будут обновляться при изменении устройства.",
"remove_area_id": "Удалить помещение",
"remove_device_id": "Удалить устройство",
"remove_entity_id": "Удалить объект"
},
"user-picker": {
"add_user": "Добавить пользователя",
"no_user": "Нет пользователя",
@@ -732,6 +744,7 @@
"editor": {
"confirm_delete": "Вы уверены, что хотите удалить эту запись?",
"delete": "Удалить",
"device_disabled": "Родительское устройство этого объекта скрыто.",
"enabled_cause": "Инициатор: {cause}.",
"enabled_delay_confirm": "Объекты будут добавлены в Home Assistant через {delay} секунд",
"enabled_description": "Скрытые объекты не будут доступны в Home Assistant.",
@@ -742,6 +755,7 @@
"icon_error": "Параметр должен быть в формате 'prefix:iconname' (например: 'mdi:home')",
"name": "Название",
"note": "(может работать не со всеми интеграциями)",
"open_device_settings": "Открыть настройки устройства",
"unavailable": "Этот объект в настоящее время недоступен.",
"update": "Обновить"
},
@@ -811,7 +825,10 @@
"controls": "Управление",
"cover": {
"close_cover": "Закрыть",
"open_cover": "Открыть"
"close_tile_cover": "Закрыть",
"open_cover": "Открыть",
"open_tilt_cover": "Открыть",
"stop_cover": "Остановить"
},
"details": "Свойства",
"dismiss": "Закрыть диалог",
@@ -879,6 +896,7 @@
"navigation": {
"areas": "Помещения",
"automation": "Автоматизация",
"blueprint": "Проекты",
"core": "Общие",
"customize": "Кастомизация",
"devices": "Устройства",
@@ -1049,7 +1067,18 @@
"caption": "Автоматизация",
"description": "Управление правилами автоматизации",
"dialog_new": {
"header": "Новая автоматизация"
"blueprint": {
"use_blueprint": "Использовать проект"
},
"header": "Новая автоматизация",
"how": "Каким образом Вы хотели бы создать автоматизацию?",
"start_empty": "Начать с пустой автоматизации",
"thingtalk": {
"create": "Создать",
"header": "Описать автоматизацию, которую Вы хотите создать",
"input_label": "Что должна делать эта автоматизация?",
"intro": "И мы попробуем преобразовать её из текста. Например: Turn the lights off when I leave."
}
},
"editor": {
"actions": {
@@ -1131,6 +1160,14 @@
"unsupported_action": "Отсутствует форма ввода для этого действия: {action}"
},
"alias": "Название",
"blueprint": {
"blueprint_to_use": "Используемый проект",
"header": "Проект",
"inputs": "Исходные данные",
"manage_blueprints": "Управление проектами",
"no_blueprints": "У Вас еще нет проектов.",
"no_inputs": "Для этого проекта не требуется указание исходных данных."
},
"conditions": {
"add": "Добавить условие",
"delete": "Удалить",
@@ -1373,6 +1410,39 @@
}
}
},
"blueprint": {
"add": {
"error_no_url": "Введите URL-адрес проекта.",
"file_name": "Название локального файла проекта",
"header": "Добавить новый проект",
"import_btn": "Импортировать проект",
"import_header": "Импорт проекта \"{name}\" (тип: {domain})",
"import_introduction": "Вы можете импортировать проекты других пользователей из Github и форумов сообщества. Для этого введите в этом окне URL-адрес проекта.",
"importing": "Импортирование проекта...",
"raw_blueprint": "Состав проекта",
"save_btn": "Сохранить проект",
"saving": "Сохранение проекта...",
"unsupported_blueprint": "Этот проект не поддерживается",
"url": "URL-адрес проекта"
},
"caption": "Проекты",
"description": "Управление проектами",
"overview": {
"add_blueprint": "Импортировать проект",
"confirm_delete_header": "Удалить этот проект?",
"confirm_delete_text": "Вы уверены, что хотите удалить этот проект?",
"delete_blueprint": "Удалить проект",
"header": "Редактор проекта",
"headers": {
"domain": "Домен",
"file_name": "Название файла",
"name": "Название"
},
"introduction": "С помощью этого редактора Вы можете создавать и редактировать проекты.",
"learn_more": "Узнайте больше о проектах",
"use_blueprint": "Создать автоматизацию"
}
},
"cloud": {
"account": {
"alexa": {
@@ -1610,6 +1680,7 @@
"unknown_condition": "Неизвестное условие"
},
"create": "Создать автоматизацию",
"create_disable": "Скрытые устройства нельзя использовать для создания автоматизаций",
"no_automations": "Нет автоматизаций",
"no_device_automations": "Для этого устройства нет средств автоматизации.",
"triggers": {
@@ -1638,6 +1709,15 @@
"description": "Управление подключенными устройствами",
"device_info": "Устройство",
"device_not_found": "Устройство не найдено",
"disabled": "Скрыто",
"disabled_by": {
"config_entry": "Конфигурация",
"integration": "Интеграция",
"user": "Пользователь"
},
"enabled_cause": "Инициатор: {cause}.",
"enabled_description": "Скрытые устройства и их дочерние объекты не будут доступны в Home Assistant.",
"enabled_label": "Отображать устройство",
"entities": {
"add_entities_lovelace": "Добавить объекты в Lovelace UI",
"disabled_entities": "Показать {count} {count, plural,\n one {скрытый объект}\n other {скрытых объектов}\n}",
@@ -1647,14 +1727,25 @@
},
"name": "Название",
"no_devices": "Нет устройств",
"picker": {
"filter": {
"filter": "Фильтр",
"hidden_devices": "{number} {number, plural,\n one {скрытое устройство}\n other {скрытых устройств}\n}",
"show_all": "Показать все",
"show_disabled": "Скрытые устройства"
},
"search": "Поиск устройств"
},
"scene": {
"create": "Создать сцену",
"create_disable": "Скрытые устройства нельзя использовать для создания сцен",
"no_scenes": "Нет сцен",
"scenes": "Сцены"
},
"scenes": "Сцены",
"script": {
"create": "Создать сценарий",
"create_disable": "Скрытые устройства нельзя использовать для создания сценариев",
"no_scripts": "Нет сценариев",
"scripts": "Сценарии"
},
@@ -1687,6 +1778,7 @@
},
"header": "Объекты",
"headers": {
"area": "Помещение",
"entity_id": "ID объекта",
"integration": "Интеграция",
"name": "Название",
@@ -2335,6 +2427,7 @@
"editor": {
"activate_user": "Активировать",
"active": "Активен",
"active_tooltip": "Разрешает или запрещает пользователю вход в систему",
"admin": "Администратор",
"caption": "Просмотр пользователя",
"change_password": "Изменить пароль",
@@ -2414,6 +2507,16 @@
"value": "Значение"
},
"description": "Управление сетью Zigbee Home Automation",
"device_pairing_card": {
"CONFIGURED": "Настройка завершена",
"CONFIGURED_status_text": "Инициализация",
"INITIALIZED": "Инициализация завершена",
"INITIALIZED_status_text": "Устройство готово к использованию",
"INTERVIEW_COMPLETE": "Опрос завершен",
"INTERVIEW_COMPLETE_status_text": "Настройка",
"PAIRED": "Найдено устройство",
"PAIRED_status_text": "Опрос начат"
},
"devices": {
"header": "Zigbee Home Automation - Устройство"
},
@@ -2930,7 +3033,8 @@
},
"picture-glance": {
"description": "Показывает изображение и состояния объектов в виде значков. Объекты в правой стороне позволяют выполнять действия, остальные объекты при нажатии отображают окно с дополнительной информацией.",
"name": "Picture Glance"
"name": "Picture Glance",
"state_entity": "Объект, определяющий состояние изображения"
},
"picture": {
"description": "Позволяет установить изображение, которое будет использоваться для навигации по различным путям в Вашем интерфейсе или для вызова службы.",
@@ -3342,10 +3446,13 @@
"change_password": {
"confirm_new_password": "Подтвердите новый пароль",
"current_password": "Текущий пароль",
"error_new_is_old": "Новый пароль должен отличаться от текущего",
"error_new_mismatch": "Введенный новый пароль не совпадает",
"error_required": "Обязательное поле",
"header": "Изменить пароль",
"new_password": "Новый пароль",
"submit": "Подтвердить"
"submit": "Подтвердить",
"success": "Пароль успешно изменён"
},
"current_user": "Добро пожаловать, {fullName}! Вы вошли в систему.",
"customize_sidebar": {

View File

@@ -2876,6 +2876,9 @@
"dropdown_label": "Панель",
"header": "Панель"
},
"enable_shortcuts": {
"header": "Гарячі клавіші"
},
"force_narrow": {
"description": "Це дозволить приховати бічну панель за замовчуванням, як і для мобільних пристроїв.",
"header": "Завжди приховувати бічну панель"

View File

@@ -2,6 +2,7 @@
"config_entry": {
"disabled_by": {
"config_entry": "配置条目",
"device": "设备",
"integration": "集成",
"user": "用户"
}
@@ -710,6 +711,16 @@
"service-picker": {
"service": "服务"
},
"target-picker": {
"add_area_id": "选择区域",
"add_device_id": "选择设备",
"add_entity_id": "选择实体",
"expand_area_id": "在它包含的单独设备和实体中展开此区域。展开后,当区域发生更改时,它不会更新设备和实体。",
"expand_device_id": "在单独的实体中展开此设备。展开后,设备发生变化时不会更新实体。",
"remove_area_id": "删除区域",
"remove_device_id": "删除设备",
"remove_entity_id": "删除实体"
},
"user-picker": {
"add_user": "添加用户",
"no_user": "没有用户",
@@ -733,6 +744,7 @@
"editor": {
"confirm_delete": "您确定要删除此条目吗?",
"delete": "删除",
"device_disabled": "该实体的设备已禁用。",
"enabled_cause": "由于 {cause} 而被禁用",
"enabled_delay_confirm": "已启用的实体将在 {delay} 秒后添加到 Home Assistant",
"enabled_description": "已禁用的实体不再添加到 Home Assistant。",
@@ -743,6 +755,7 @@
"icon_error": "图标的格式应为 prefix:iconname例如mdi:home",
"name": "名称",
"note": "注意:这可能不适用于所有集成。",
"open_device_settings": "打开设备设置",
"unavailable": "该实体暂不可用。",
"update": "更新"
},
@@ -781,7 +794,7 @@
"min": "最小值",
"mode": "显示模式",
"slider": "滑杆",
"step": "滑杆步长",
"step": "步长",
"unit_of_measurement": "单位"
},
"input_select": {
@@ -1052,7 +1065,7 @@
},
"automation": {
"caption": "自动化",
"description": "管理自动化",
"description": "为智能家居制订自动化规则",
"dialog_new": {
"blueprint": {
"use_blueprint": "使用 Blueprint"
@@ -1510,7 +1523,7 @@
"title": "Alexa"
},
"caption": "Home Assistant Cloud",
"description_features": "整合 Alexa Google 助理,远程控制智能家居。",
"description_features": "远程控制智能家居,还可接入 Alexa Google Assistant",
"description_login": "登录为 {email}",
"description_not_login": "未登录",
"dialog_certificate": {
@@ -1605,7 +1618,7 @@
},
"core": {
"caption": "通用",
"description": "更改 Home Assistant 的通用配置",
"description": "单位制、位置、时区及其他通用参数",
"section": {
"core": {
"core_config": {
@@ -1667,6 +1680,7 @@
"unknown_condition": "未知环境条件"
},
"create": "通过设备创建自动化",
"create_disable": "不能通过禁用的设备创建自动化",
"no_automations": "没有自动化",
"no_device_automations": "该设备没有可用的自动化。",
"triggers": {
@@ -1695,6 +1709,15 @@
"description": "管理已连接的设备",
"device_info": "设备信息",
"device_not_found": "未找到设备。",
"disabled": "已禁用",
"disabled_by": {
"config_entry": "配置条目",
"integration": "集成",
"user": "用户"
},
"enabled_cause": "设备已通过{cause}禁用。",
"enabled_description": "禁用的设备将不会显示,并且属于该设备的实体也将被禁用并且不会添加到 Home Assistant。",
"enabled_label": "启用设备",
"entities": {
"add_entities_lovelace": "添加到 Lovelace",
"disabled_entities": "+{count} {count, plural,\n one {个已禁用实体}\n other {个已禁用实体}\n}",
@@ -1704,14 +1727,25 @@
},
"name": "名称",
"no_devices": "没有设备",
"picker": {
"filter": {
"filter": "筛选",
"hidden_devices": "{number} 个隐藏设备",
"show_all": "显示全部",
"show_disabled": "显示已禁用的设备"
},
"search": "搜索设备"
},
"scene": {
"create": "通过设备创建场景",
"create_disable": "不能通过禁用的设备创建场景",
"no_scenes": "没有场景",
"scenes": "场景"
},
"scenes": "场景",
"script": {
"create": "通过设备创建脚本",
"create_disable": "不能通过禁用的设备创建脚本",
"no_scripts": "没有脚本",
"scripts": "脚本"
},
@@ -1744,6 +1778,7 @@
},
"header": "实体",
"headers": {
"area": "区域",
"entity_id": "实体 ID",
"integration": "集成",
"name": "名称",
@@ -1755,7 +1790,7 @@
"button": "删除所选实体",
"confirm_partly_text": "在所选的 {selected} 个实体中有 {removable} 个可被删除。实体可被删除的条件是集成不再提供它们。有时,即使集成已删除,也必须先重新启动 Home Assistant 才能删除它们的实体。您确定要删除实体吗?",
"confirm_partly_title": "所选实体中只有 {number} 个可被删除。",
"confirm_text": "如果它们包含这些实体,则应将它们从 Lovelace 配置和自动化中删除。",
"confirm_text": "如果 Lovelace 配置和自动化中包含这些实体,请将它们一并删除。",
"confirm_title": "您要删除这 {number} 个实体吗?"
},
"search": "搜索实体",
@@ -1776,7 +1811,7 @@
"header": "配置 Home Assistant",
"helpers": {
"caption": "辅助元素",
"description": "管理辅助构建自动化的元素",
"description": "辅助构建自动化的元素",
"dialog": {
"add_helper": "添加辅助元素",
"add_platform": "添加 {platform}",
@@ -1808,7 +1843,7 @@
"copy_github": "用于 GitHub",
"copy_raw": "原始文本",
"custom_uis": "自定义用户界面:",
"description": "查看关于此 Home Assistant 安装的信息",
"description": "Home Assistant 的版本号、系统状态和各类文档的链接",
"developed_by": "由一帮很 Awesome~~~ 的人开发。",
"documentation": "文档",
"frontend": "前端用户界面",
@@ -1999,7 +2034,7 @@
"open": "打开"
}
},
"description": "管理 Lovelace 仪表盘",
"description": "自定义卡片布局,让控制设备更方便",
"resources": {
"cant_edit_yaml": "您正在 YAML 模式下使用 Lovelace因此无法通过 UI 管理资源。请在 configuration.yaml 中管理它们。",
"caption": "资源",
@@ -2198,19 +2233,19 @@
"scene": {
"activated": "已激活场景 {name}。",
"caption": "场景",
"description": "管理场景",
"description": "定格一组设备的状态,日后即可一键恢复",
"editor": {
"default_name": "新场景",
"devices": {
"add": "添加设备",
"delete": "删除设备",
"header": "设备",
"introduction": "添加要包含在场景中的设备。将所有设备设置该场景所需的状态。"
"introduction": "在此添加要包含在场景中的设备,然后将它们设置该场景所需的状态。"
},
"entities": {
"add": "添加实体",
"delete": "删除实体",
"device_entities": "如果添加属于设备的实体,则将添加设备。",
"device_entities": "如果添加的实体属于设备,仍会添加设备。",
"header": "实体",
"introduction": "可在此处设置不属于设备的实体。",
"without_device": "无设备关联的实体"
@@ -2242,7 +2277,7 @@
},
"script": {
"caption": "脚本",
"description": "管理脚本",
"description": "执行一系列动作",
"editor": {
"alias": "名称",
"default_name": "新建脚本",
@@ -2353,7 +2388,7 @@
"confirm_remove": "您确定要删除标签 {tag} 吗?",
"confirm_remove_title": "删除标签?",
"create_automation": "通过标签创建自动化",
"description": "管理标签",
"description": "NFC 标签和二维码也可以触发自动化",
"detail": {
"companion_apps": "配套应用程序",
"create": "创建",
@@ -2392,6 +2427,7 @@
"editor": {
"activate_user": "激活用户",
"active": "激活",
"active_tooltip": "控制用户能否登录",
"admin": "管理员",
"caption": "用户信息",
"change_password": "更改密码",
@@ -2471,6 +2507,16 @@
"value": "值"
},
"description": "Zigbee 智能家居(ZHA) 网络管理",
"device_pairing_card": {
"CONFIGURED": "配置完成",
"CONFIGURED_status_text": "正在初始化",
"INITIALIZED": "初始化完成",
"INITIALIZED_status_text": "设备可以使用了",
"INTERVIEW_COMPLETE": "协商完成",
"INTERVIEW_COMPLETE_status_text": "正在配置",
"PAIRED": "发现设备",
"PAIRED_status_text": "开始协商"
},
"devices": {
"header": "Zigbee 家庭自动化 - 设备"
},
@@ -3400,10 +3446,13 @@
"change_password": {
"confirm_new_password": "确认新密码",
"current_password": "当前密码",
"error_new_is_old": "新密码不能与当前密码相同",
"error_new_mismatch": "输入的新密码不一致",
"error_required": "必填",
"header": "更改密码",
"new_password": "新密码",
"submit": "提交"
"submit": "提交",
"success": "密码修改成功"
},
"current_user": "您目前以 {fullName} 的身份登录。",
"customize_sidebar": {

View File

@@ -2,6 +2,7 @@
"config_entry": {
"disabled_by": {
"config_entry": "設定實體",
"device": "裝置",
"integration": "整合",
"user": "使用者"
}
@@ -597,21 +598,21 @@
"set": "設定",
"turned_off": "關閉",
"turned_on": "開啟",
"was_at_home": "狀態在家",
"was_at_state": "狀態{state}",
"was_away": "狀態離家",
"was_closed": "狀態關閉",
"was_connected": "狀態連線",
"was_disconnected": "狀態斷線",
"was_locked": "狀態上鎖",
"was_low": "狀態過低",
"was_normal": "狀態正常",
"was_opened": "狀態開啟",
"was_plugged_in": "狀態插上",
"was_safe": "狀態安全",
"was_unlocked": "狀態解鎖",
"was_unplugged": "狀態拔下",
"was_unsafe": "狀態不安全"
"was_at_home": "狀態在家",
"was_at_state": "狀態{state}",
"was_away": "狀態離家",
"was_closed": "狀態關閉",
"was_connected": "狀態連線",
"was_disconnected": "狀態斷線",
"was_locked": "狀態上鎖",
"was_low": "狀態過低",
"was_normal": "狀態正常",
"was_opened": "狀態開啟",
"was_plugged_in": "狀態插上",
"was_safe": "狀態安全",
"was_unlocked": "狀態解鎖",
"was_unplugged": "狀態拔下",
"was_unsafe": "狀態不安全"
}
},
"media-browser": {
@@ -710,6 +711,16 @@
"service-picker": {
"service": "服務"
},
"target-picker": {
"add_area_id": "選擇區域",
"add_device_id": "選擇裝置",
"add_entity_id": "選擇實體",
"expand_area_id": "在它包含的單獨的裝置和實體中擴展此區域。擴展後,區域更改時將不會更新裝置和實體。",
"expand_device_id": "在它包含的單獨的裝置和實體中擴展此區域。擴展後,區域更改時將不會更新裝置和實體。",
"remove_area_id": "移除區域",
"remove_device_id": "移除裝置",
"remove_entity_id": "移除實體"
},
"user-picker": {
"add_user": "新增使用者",
"no_user": "沒有使用者",
@@ -733,6 +744,7 @@
"editor": {
"confirm_delete": "確定要刪除此實體?",
"delete": "刪除",
"device_disabled": "該實體目前不可用。",
"enabled_cause": "由 {cause} 關閉。",
"enabled_delay_confirm": "啟用的實體將會於 {delay} 秒後新增至 Home Assistant",
"enabled_description": "關閉的實體將不會新增至 Home Assistant。",
@@ -743,6 +755,7 @@
"icon_error": "圖示必須按照格式「prefix:iconname」設定例如「mdi:home」",
"name": "名稱",
"note": "注意:可能無法適用所有整合。",
"open_device_settings": "打開裝置設置",
"unavailable": "該實體目前不可用。",
"update": "更新"
},
@@ -829,7 +842,7 @@
"restored": {
"confirm_remove_text": "確定要移除此實體?",
"confirm_remove_title": "移除實體?",
"not_provided": "此實體目前不可用,屬於獨立可移除、變更或失常的整合或設備。",
"not_provided": "此實體目前不可用,屬於獨立可移除、變更或失常的整合或裝置。",
"remove_action": "移除實體",
"remove_intro": "假如實體不再使用,可以藉由移除進行清除。"
},
@@ -961,7 +974,7 @@
"zigbee_information": "Zigbee 裝置簽章"
},
"confirmations": {
"remove": "確定要移除此設備"
"remove": "確定要移除此裝置"
},
"device_signature": "Zigbee 裝置簽章",
"last_seen": "上次出現",
@@ -970,9 +983,9 @@
"power_source": "電力來源",
"quirk": "Quirk",
"services": {
"reconfigure": "重新設定 ZHA Zibgee 設備(健康設備)。假如遇到設備問題,請使用此選項。假如有問題的設備為使用電池的設備,請先確定設備已喚醒並處於接受命令狀態。",
"reconfigure": "重新設定 ZHA Zibgee 裝置(健康裝置)。假如遇到裝置問題,請使用此選項。假如有問題的裝置為使用電池的裝置,請先確定裝置已喚醒並處於接受命令狀態。",
"remove": "從 Zigbee 網路移除裝置。",
"updateDeviceName": "於實體 ID 中自訂此設備名稱。",
"updateDeviceName": "於實體 ID 中自訂此裝置名稱。",
"zigbee_information": "檢視裝置的 Zigbee 資訊。"
},
"unknown": "未知",
@@ -1027,10 +1040,10 @@
"devices": "裝置"
},
"delete": {
"confirmation_text": "所有該分區所屬設備都將變成未指派狀態。",
"confirmation_text": "所有該分區所屬裝置都將變成未指派狀態。",
"confirmation_title": "確定要刪除此分區?"
},
"description": "管理家中所有分區",
"description": "群組分區裝置",
"editor": {
"area_id": "分區 ID",
"create": "建立",
@@ -1045,14 +1058,14 @@
"create_area": "新增分區",
"header": "分區",
"integrations_page": "整合頁面",
"introduction": "分區主要用以管理設備所在位置。此資訊將會於 Home Assistant 中使用以協助您管理介面、權限,並與其他系統進行整合。",
"introduction2": "欲於分區中放置設備,請使用下方連結至整合頁面,並點選設定整合以設定設備面板。",
"introduction": "分區主要用以管理裝置所在位置。此資訊將會於 Home Assistant 中使用以協助您管理介面、權限,並與其他系統進行整合。",
"introduction2": "欲於分區中放置裝置,請使用下方連結至整合頁面,並點選設定整合以設定裝置面板。",
"no_areas": "看起來你還沒有建立分區!"
}
},
"automation": {
"caption": "自動化",
"description": "管理自動化",
"description": "為家庭新增自訂自動化",
"dialog_new": {
"blueprint": {
"use_blueprint": "使用 Blueprint"
@@ -1438,8 +1451,8 @@
"enable": "開啟",
"enable_ha_skill": "開啟 Home Assistant skill for Alexa",
"enable_state_reporting": "開啟狀態回報",
"info": "藉由 Home Assistant Cloud 雲服務 Alexa 整合,將能透過 Alexa 支援設備以控制所有 Home Assistant 設備。",
"info_state_reporting": "假如開啟狀態回報Home Assistant 將會持續傳送所有連結實體的狀態改變至 Amazon。以確保於 Alexa app 中設備永遠保持最新狀態、並藉以創建例行自動化。",
"info": "藉由 Home Assistant Cloud 雲服務 Alexa 整合,將能透過 Alexa 支援裝置以控制所有 Home Assistant 裝置。",
"info_state_reporting": "假如開啟狀態回報Home Assistant 將會持續傳送所有連結實體的狀態改變至 Amazon。以確保於 Alexa app 中裝置永遠保持最新狀態、並藉以創建例行自動化。",
"manage_entities": "管理實體",
"state_reporting_error": "無法 {enable_disable} 回報狀態。",
"sync_entities": "同步實體",
@@ -1455,10 +1468,10 @@
"enable_ha_skill": "啟用 Home Assistant skill for Google Assistant",
"enable_state_reporting": "開啟狀態回報",
"enter_pin_error": "無法儲存 Pin",
"enter_pin_hint": "請輸入安全碼以使用加密設備",
"enter_pin_info": "請輸入加密設備 Pin 碼、加密設備為如門、車庫與門鎖。當透過 Google Assistant 與此類設備進行互動時,將需要語音說出/輸入密碼。",
"info": "藉由 Home Assistant Cloud 雲服務 Google Assistant 整合,將能透過 Google Assistant 支援設備以控制所有 Home Assistant 設備。",
"info_state_reporting": "假如開啟狀態回報Home Assistant 將會持續傳送所有連結實體的狀態改變至 Google。以確保於 Google app 中設備永遠保持最新狀態、並藉以創建例行自動化。",
"enter_pin_hint": "請輸入安全碼以使用加密裝置",
"enter_pin_info": "請輸入加密裝置 Pin 碼、加密裝置為如門、車庫與門鎖。當透過 Google Assistant 與此類裝置進行互動時,將需要語音說出/輸入密碼。",
"info": "藉由 Home Assistant Cloud 雲服務 Google Assistant 整合,將能透過 Google Assistant 支援裝置以控制所有 Home Assistant 裝置。",
"info_state_reporting": "假如開啟狀態回報Home Assistant 將會持續傳送所有連結實體的狀態改變至 Google。以確保於 Google app 中裝置永遠保持最新狀態、並藉以創建例行自動化。",
"manage_entities": "管理實體",
"security_devices": "安全裝置",
"sync_entities": "與 Google 同步實體",
@@ -1476,8 +1489,8 @@
"access_is_being_prepared": "遠端登入準備中,會於就緒時通知您。",
"certificate_info": "認證資訊",
"info": "Home Assistant Cloud 雲服務提供您離家時、遠端加密連線控制。",
"instance_is_available": "您的設備可透過下方連結使用",
"instance_will_be_available": "您的設備將可透過下方連結使用",
"instance_is_available": "您的裝置可透過下方連結使用",
"instance_will_be_available": "您的裝置將可透過下方連結使用",
"link_learn_how_it_works": "了解如何運作",
"title": "遠端控制"
},
@@ -1510,7 +1523,7 @@
"title": "Alexa"
},
"caption": "Home Assistant Cloud",
"description_features": "整合 Alexa 及 Google 助理,遠端控制智慧型家居",
"description_features": "遠端控制家庭與 Alexa 及 Google 助理整合",
"description_login": "登入帳號:{email}",
"description_not_login": "未登入",
"dialog_certificate": {
@@ -1605,7 +1618,7 @@
},
"core": {
"caption": "一般設定",
"description": "變更 Home Assistant 一般設定",
"description": "單位系統、座標、時區與其他一般設定",
"section": {
"core": {
"core_config": {
@@ -1666,9 +1679,10 @@
"no_conditions": "無觸發條件",
"unknown_condition": "未知觸發條件"
},
"create": "以設備新增自動化",
"create": "以裝置新增自動化",
"create_disable": "以裝置新增自動化",
"no_automations": "沒有自動化",
"no_device_automations": "該設備沒有任何自動化可使用。",
"no_device_automations": "該裝置沒有任何自動化可使用。",
"triggers": {
"caption": "執行動作、當...",
"no_triggers": "無觸發",
@@ -1692,9 +1706,18 @@
"no_devices": "沒有任何裝置"
},
"delete": "刪除",
"description": "管理已連線的裝置",
"description": "管理已設定裝置",
"device_info": "裝置資訊",
"device_not_found": "找不到裝置。",
"disabled": "已關閉",
"disabled_by": {
"config_entry": "設定實體",
"integration": "整合類型",
"user": "使用者"
},
"enabled_cause": "由 {cause} 關閉。",
"enabled_description": "關閉的實體將不會新增至 Home Assistant。",
"enabled_label": "開啟裝置事件",
"entities": {
"add_entities_lovelace": "新增至 Lovelace UI",
"disabled_entities": "{count} {count, plural,\n one {個已關閉實體}\n other {個已關閉實體}\n}",
@@ -1704,14 +1727,25 @@
},
"name": "名稱",
"no_devices": "沒有任何裝置",
"picker": {
"filter": {
"filter": "過濾器",
"hidden_devices": "{number} 隱藏 {number, plural,\n one {個裝置}\n other {個裝置}\n}",
"show_all": "顯示全部",
"show_disabled": "顯示關閉實體"
},
"search": "尋找裝置"
},
"scene": {
"create": "以設備新增場景",
"create": "以裝置新增場景",
"create_disable": "以裝置新增場景",
"no_scenes": "沒有場景",
"scenes": "場景"
},
"scenes": "場景",
"script": {
"create": "以設備新增腳本",
"create": "以裝置新增腳本",
"create_disable": "以裝置新增腳本",
"no_scripts": "沒有腳本",
"scripts": "腳本"
},
@@ -1744,6 +1778,7 @@
},
"header": "實體",
"headers": {
"area": "分區",
"entity_id": "實體 ID",
"integration": "整合",
"name": "名稱",
@@ -1776,7 +1811,7 @@
"header": "設定 Home Assistant",
"helpers": {
"caption": "助手",
"description": "管理可協助建立自動化的元素",
"description": "協助建立自動化的元素",
"dialog": {
"add_helper": "新增助手",
"add_platform": "新增 {platform}",
@@ -1808,7 +1843,7 @@
"copy_github": "GitHub",
"copy_raw": "原始文字",
"custom_uis": "自定介面:",
"description": "檢視 Home Assistant 安裝資訊",
"description": "版本、系統健康度與文件連結",
"developed_by": "由一群充滿熱情的人們所開發。",
"documentation": "相關文件",
"frontend": "frontend-ui",
@@ -1874,7 +1909,7 @@
"delete": "刪除",
"delete_button": "刪除 {integration}",
"delete_confirm": "確定要刪除此整合?",
"device_unavailable": "設備不可用",
"device_unavailable": "裝置不可用",
"devices": "{count} {count, plural,\n one {個裝置}\n other {個裝置}\n}",
"documentation": "相關文件",
"entities": "{count} {count, plural,\n one {個實體}\n other {個實體}\n}",
@@ -1914,7 +1949,7 @@
},
"configure": "設定",
"configured": "已設定整合",
"description": "管理整合",
"description": "管理服務、裝置整合",
"details": "整合詳細資訊",
"discovered": "已掃描",
"home_assistant_website": "Home Assistant 網站",
@@ -1976,9 +2011,9 @@
"edit_dashboard": "編輯主面板",
"icon": "圖示",
"new_dashboard": "新增主面板",
"remove_default": "移除此設備預設值",
"remove_default": "移除此裝置預設值",
"require_admin": "僅限管理員",
"set_default": "設定為此設備預設值",
"set_default": "設定為此裝置預設值",
"show_sidebar": "於側邊列顯示",
"title": "標題",
"title_required": "必須輸入標題",
@@ -1999,7 +2034,7 @@
"open": "開啟"
}
},
"description": "管理 Lovelace 主面板",
"description": "創建自訂面板設定以控制家庭",
"resources": {
"cant_edit_yaml": "正使用 YAML 模式、因此無法藉由 UI 變更 Lovelace 設定。請於「configuration.yaml」進行管理。",
"caption": "資源",
@@ -2176,7 +2211,7 @@
"confirm_delete_user": "確定要刪除帳號{name}使用者?依舊可以追蹤使用者,但人員將無法進行登入。",
"create": "新增",
"delete": "刪除",
"device_tracker_intro": "選擇此人員所擁有的設備。",
"device_tracker_intro": "選擇此人員所擁有的裝置。",
"device_tracker_pick": "選擇要追蹤的裝置",
"device_tracker_picked": "追蹤裝置",
"link_integrations_page": "整合頁面",
@@ -2185,7 +2220,7 @@
"name": "名稱",
"name_error_msg": "必須輸入名稱",
"new_person": "新人員",
"no_device_tracker_available_intro": "當有設備顯示有人員在場時、可以將該設備指定為某個人員所有。可以先藉由整合頁面、新增人員偵測整合以加入第一個設備。",
"no_device_tracker_available_intro": "當有裝置顯示有人員在場時、可以將該裝置指定為某個人員所有。可以先藉由整合頁面、新增人員偵測整合以加入第一個裝置。",
"update": "更新"
},
"introduction": "此處可定義 Home Assistant 中的每一位成員。",
@@ -2198,22 +2233,22 @@
"scene": {
"activated": "已啟用場景 {name}。",
"caption": "場景",
"description": "管理場景",
"description": "獲取裝置狀態及稍候進行調用",
"editor": {
"default_name": "新場景",
"devices": {
"add": "新增裝置",
"delete": "移除裝置",
"header": "裝置",
"introduction": "新增所要包含於場景中的設備,設定所有設備成此場景中所希望的狀態。"
"introduction": "新增所要包含於場景中的裝置,設定所有裝置成此場景中所希望的狀態。"
},
"entities": {
"add": "新增實體",
"delete": "刪除實體",
"device_entities": "假如新增一項屬於設備的實體,設備也將被新增。",
"device_entities": "假如新增一項屬於裝置的實體,裝置也將被新增。",
"header": "實體",
"introduction": "不屬於設備的實體可以於此設置。",
"without_device": "無設備實體"
"introduction": "不屬於裝置的實體可以於此設置。",
"without_device": "無裝置實體"
},
"icon": "圖示",
"introduction": "使用場景來讓你的智慧型家居更有魅力吧。",
@@ -2242,7 +2277,7 @@
},
"script": {
"caption": "腳本",
"description": "管理腳本",
"description": "執行連續動作腳本",
"editor": {
"alias": "名稱",
"default_name": "新腳本",
@@ -2353,7 +2388,7 @@
"confirm_remove": "是否要移除標籤 {tag}",
"confirm_remove_title": "移除標籤?",
"create_automation": "以標籤新增自動化",
"description": "管理標籤",
"description": "當 NFC 標籤或 QR Code 掃描時、觸發自動化",
"detail": {
"companion_apps": "行動程式 App",
"create": "新增",
@@ -2392,6 +2427,7 @@
"editor": {
"activate_user": "啟用使用者",
"active": "啟用",
"active_tooltip": "控制用戶是否可以登錄",
"admin": "管理員",
"caption": "檢視使用者",
"change_password": "更改密碼",
@@ -2425,19 +2461,19 @@
"users_privileges_note": "使用者群組功能仍在開發中。將無法透過 UI 進行使用者管理,仍在檢視所有管理 API Endpoint 以確保能夠正確符合管理員存取需求。"
},
"zha": {
"add_device": "新增設備",
"add_device": "新增裝置",
"add_device_page": {
"discovered_text": "在探索到裝置後將顯示於此處。",
"discovery_text": "所發現的設備將會顯示於此。跟隨設備的指示並將其設定為配對模式。",
"header": "Zigbee 家庭自動化 - 新增設備",
"no_devices_found": "找不到設備,請確定設備處於配對模式、並於探索時保持喚醒狀態。",
"pairing_mode": "請確定設備處於配對模式中,參閱設備的手冊以了解如何進行操作。",
"discovery_text": "所發現的裝置將會顯示於此。跟隨裝置的指示並將其設定為配對模式。",
"header": "Zigbee 家庭自動化 - 新增裝置",
"no_devices_found": "找不到裝置,請確定裝置處於配對模式、並於探索時保持喚醒狀態。",
"pairing_mode": "請確定裝置處於配對模式中,參閱裝置的手冊以了解如何進行操作。",
"search_again": "再次搜尋",
"spinner": "正在搜尋 ZHA Zigbee 設備..."
"spinner": "正在搜尋 ZHA Zigbee 裝置..."
},
"add": {
"caption": "新增裝置",
"description": "新增設備至 Zigbee 網路"
"description": "新增裝置至 Zigbee 網路"
},
"button": "設定",
"caption": "ZHA",
@@ -2471,18 +2507,28 @@
"value": "數值"
},
"description": "Zigbee 家庭自動化網路管理",
"device_pairing_card": {
"CONFIGURED": "設定完成",
"CONFIGURED_status_text": "初始化中",
"INITIALIZED": "初始化完成",
"INITIALIZED_status_text": "裝置已準備就緒",
"INTERVIEW_COMPLETE": "探訪完成",
"INTERVIEW_COMPLETE_status_text": "設定中",
"PAIRED": "找到裝置",
"PAIRED_status_text": "開始探訪"
},
"devices": {
"header": "Zigbee 家庭自動化 - 設備"
"header": "Zigbee 家庭自動化 - 裝置"
},
"group_binding": {
"bind_button_help": "綁定所選擇之群組至所選擇之設備叢集。",
"bind_button_help": "綁定所選擇之群組至所選擇之裝置叢集。",
"bind_button_label": "綁定群組",
"cluster_selection_help": "選擇叢集以綁定至所選群組。",
"group_picker_help": "選擇群組進行綁定命令。",
"group_picker_label": "可綁定群組",
"header": "群組綁定",
"introduction": "綁定與解除綁定群組。",
"unbind_button_help": "由所選擇之設備叢集中取消綁定所選擇之群組。",
"unbind_button_help": "由所選擇之裝置叢集中取消綁定所選擇之群組。",
"unbind_button_label": "解除綁定群組"
},
"groups": {
@@ -2524,10 +2570,10 @@
},
"node_management": {
"header": "裝置管理",
"help_node_dropdown": "選擇設備以檢視該設備選項。",
"hint_battery_devices": "請注意:對設備執行命令時,需喚醒處於睡眠狀態的設備(使用電池供電),通常可以藉由觸發以喚醒設備。",
"help_node_dropdown": "選擇裝置以檢視該裝置選項。",
"hint_battery_devices": "請注意:對裝置執行命令時,需喚醒處於睡眠狀態的裝置(使用電池供電),通常可以藉由觸發以喚醒裝置。",
"hint_wakeup": "在您進行互動時某些裝置(例如小米感應器)有喚醒按鈕、可藉由每隔約 5 秒按一下、以保持該裝置處於喚醒狀態。",
"introduction": "執行 ZHA 命命將影響單一設備。選擇設備以檢視該設備可使用之命令。"
"introduction": "執行 ZHA 命命將影響單一裝置。選擇裝置以檢視該裝置可使用之命令。"
},
"title": "Zigbee 家庭自動化",
"visualization": {
@@ -2552,7 +2598,7 @@
"name": "名稱",
"new_zone": "新區域",
"passive": "被動",
"passive_note": "被動區域將會於前端中隱藏、不會作為設備位置追蹤。使用於僅作為自動化之用相當方便。",
"passive_note": "被動區域將會於前端中隱藏、不會作為裝置位置追蹤。使用於僅作為自動化之用相當方便。",
"radius": "半徑",
"required_error_msg": "必填欄位",
"update": "更新"
@@ -2697,7 +2743,7 @@
"attributes": "屬性",
"current_entities": "目前實體",
"description1": "設定 Home Assistant 裝置代表。",
"description2": "將不會與實際設備進行通訊。",
"description2": "將不會與實際裝置進行通訊。",
"entity": "實體",
"filter_attributes": "屬性過濾器",
"filter_entities": "實體過濾器",
@@ -2760,7 +2806,7 @@
"confirm_delete": "確定要刪除此面板?",
"empty_state": {
"go_to_integrations_page": "轉至整合頁面。",
"no_devices": "此頁面允許進行控制所擁有的設備。看起來您尚未設定任何設備,從設定中的整合頁面開始吧。",
"no_devices": "此頁面允許進行控制所擁有的裝置。看起來您尚未設定任何裝置,從設定中的整合頁面開始吧。",
"title": "歡迎回家"
},
"entities": {
@@ -3114,7 +3160,7 @@
"header": "移動至哪個面板"
},
"raw_editor": {
"confirm_remove_config_text": "假如移除 Lovelace UI 設定的話,將自動以區域與設備產生 Lovelace UI 視圖。",
"confirm_remove_config_text": "假如移除 Lovelace UI 設定的話,將自動以區域與裝置產生 Lovelace UI 視圖。",
"confirm_remove_config_title": "確定要移除 Lovelace UI 設定?",
"confirm_unsaved_changes": "變更尚未儲存,確定要退出?",
"confirm_unsaved_comments": "設定包含命令、將不會被儲存。是否要繼續?",
@@ -3235,7 +3281,7 @@
"data": {
"code": "雙重驗證碼"
},
"description": "開啟設備上的 **{mfa_module_name}** 以獲得雙重驗證碼,並進行驗證:"
"description": "開啟裝置上的 **{mfa_module_name}** 以獲得雙重驗證碼,並進行驗證:"
}
}
},
@@ -3258,7 +3304,7 @@
"data": {
"code": "雙重驗證碼"
},
"description": "開啟設備上的 **{mfa_module_name}** 以獲得雙重驗證碼,並進行驗證:"
"description": "開啟裝置上的 **{mfa_module_name}** 以獲得雙重驗證碼,並進行驗證:"
}
}
},
@@ -3282,7 +3328,7 @@
"data": {
"code": "雙重驗證碼"
},
"description": "開啟設備上的 **{mfa_module_name}** 以獲得雙重驗證碼,並進行驗證:"
"description": "開啟裝置上的 **{mfa_module_name}** 以獲得雙重驗證碼,並進行驗證:"
}
}
},
@@ -3365,7 +3411,7 @@
},
"integration": {
"finish": "完成",
"intro": "將會於 Home Assistant 整合中呈現的設備與服務。可以現在進行設定,或者稍後於設定選單中進行。",
"intro": "將會於 Home Assistant 整合中呈現的裝置與服務。可以現在進行設定,或者稍後於設定選單中進行。",
"more_integrations": "更多"
},
"intro": "準備喚醒您的智慧型家庭、取得隱私自主權,並加入由全球愛好者共同維護的社群了嗎?",
@@ -3400,10 +3446,13 @@
"change_password": {
"confirm_new_password": "確認密碼",
"current_password": "目前密碼",
"error_new_is_old": "新密碼必須與當前密碼不同",
"error_new_mismatch": "輸入的新密碼值不匹配",
"error_required": "必填",
"header": "變更密碼",
"new_password": "新密碼",
"submit": "傳送"
"submit": "傳送",
"success": "密碼變更成功"
},
"current_user": "目前登入身份:{fullName}。",
"customize_sidebar": {
@@ -3466,7 +3515,7 @@
"push_notifications": {
"add_device_prompt": {
"input_label": "裝置名稱",
"title": "要幫這個裝置取什麼名呢?"
"title": "要幫這個裝置取什麼名呢?"
},
"description": "推送通知到這個裝置。",
"error_load_platform": "設定 notify.html5。",