Merge pull request #3450 from home-assistant/dev

20190801.0
This commit is contained in:
Paulus Schoutsen 2019-08-01 13:41:22 -07:00 committed by GitHub
commit 1f13c00937
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 864 additions and 456 deletions

View File

@ -2,7 +2,7 @@ from setuptools import setup, find_packages
setup(
name="home-assistant-frontend",
version="20190731.0",
version="20190801.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,19 @@
// https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1
export const slugify = (value: string) => {
const a =
"àáäâãåăæąçćčđďèéěėëêęğǵḧìíïîįłḿǹńňñòóöôœøṕŕřßşśšșťțùúüûǘůűūųẃẍÿýźžż·/_,:;";
const b =
"aaaaaaaaacccddeeeeeeegghiiiiilmnnnnooooooprrsssssttuuuuuuuuuwxyyzzz------";
const p = new RegExp(a.split("").join("|"), "g");
return value
.toString()
.toLowerCase()
.replace(/\s+/g, "-") // Replace spaces with -
.replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters
.replace(/&/g, "-and-") // Replace & with 'and'
.replace(/[^\w\-]+/g, "") // Remove all non-word characters
.replace(/\-\-+/g, "-") // Replace multiple - with single -
.replace(/^-+/, "") // Trim - from start of text
.replace(/-+$/, ""); // Trim - from end of text
};

View File

@ -11,6 +11,34 @@ export interface ZWaveValue {
poll_intensity: number;
}
export interface ZWaveConfigItem {
key: number;
value: {
data: any;
data_items: any[];
help: string;
label: string;
max: number;
min: number;
type: string;
};
}
export interface ZWaveConfigServiceData {
node_id: number;
parameter: number;
value: number | string;
}
export interface ZWaveNode {
attributes: ZWaveAttributes;
}
export interface ZWaveAttributes {
node_id: number;
wake_up_interval?: number;
}
export const ZWAVE_NETWORK_STATE_STOPPED = 0;
export const ZWAVE_NETWORK_STATE_FAILED = 1;
export const ZWAVE_NETWORK_STATE_STARTED = 5;
@ -26,3 +54,6 @@ export const fetchNetworkStatus = (
export const fetchValues = (hass: HomeAssistant, nodeId: number) =>
hass.callApi<ZWaveValue[]>("GET", `zwave/values/${nodeId}`);
export const fetchNodeConfig = (hass: HomeAssistant, nodeId: number) =>
hass.callApi<ZWaveConfigItem[]>("GET", `zwave/config/${nodeId}`);

View File

@ -11,7 +11,7 @@ export const demoConfig: HassConfig = {
temperature: "°C",
volume: "L",
},
components: ["conversation", "notify.html5", "history"],
components: ["notify.html5", "history"],
time_zone: "America/Los_Angeles",
config_dir: "/config",
version: "DEMO",

View File

@ -1,377 +0,0 @@
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import { html } from "@polymer/polymer/lib/utils/html-tag";
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../components/buttons/ha-call-service-button";
import "../../../components/ha-card";
class ZwaveNodeConfig extends PolymerElement {
static get template() {
return html`
<style include="iron-flex ha-style">
.content {
margin-top: 24px;
}
ha-card {
margin: 0 auto;
max-width: 600px;
}
.device-picker {
@apply --layout-horizontal;
@apply --layout-center-center;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 24px;
}
.help-text {
padding-left: 24px;
padding-right: 24px;
}
</style>
<div class="content">
<ha-card header="Node config options">
<template is="dom-if" if="[[_wakeupNode]]">
<div class="card-actions">
<paper-input
float-label="Wakeup Interval"
type="number"
value="{{_wakeupInput}}"
placeholder="[[_computeGetWakeupValue(selectedNode)]]"
>
<div suffix="">seconds</div>
</paper-input>
<ha-call-service-button
hass="[[hass]]"
domain="zwave"
service="set_wakeup"
service-data="[[_computeWakeupServiceData(_wakeupInput)]]"
>
Set Wakeup
</ha-call-service-button>
</div>
</template>
<div class="device-picker">
<paper-dropdown-menu
label="Config parameter"
dynamic-align=""
class="flex"
>
<paper-listbox
slot="dropdown-content"
selected="{{_selectedConfigParameter}}"
>
<template is="dom-repeat" items="[[config]]" as="state">
<paper-item
>[[_computeSelectCaptionConfigParameter(state)]]</paper-item
>
</template>
</paper-listbox>
</paper-dropdown-menu>
</div>
<template
is="dom-if"
if="[[_isConfigParameterSelected(_selectedConfigParameter, 'List')]]"
>
<div class="device-picker">
<paper-dropdown-menu
label="Config value"
dynamic-align=""
class="flex"
placeholder="{{_loadedConfigValue}}"
>
<paper-listbox
slot="dropdown-content"
selected="{{_selectedConfigValue}}"
>
<template
is="dom-repeat"
items="[[_selectedConfigParameterValues]]"
as="state"
>
<paper-item>[[state]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
</div>
</template>
<template
is="dom-if"
if="[[_isConfigParameterSelected(_selectedConfigParameter, 'Byte Short Int')]]"
>
<div class="card-actions">
<paper-input
label="{{_selectedConfigParameterNumValues}}"
type="number"
value="{{_selectedConfigValue}}"
max="{{_configParameterMax}}"
min="{{_configParameterMin}}"
>
</paper-input>
</div>
</template>
<template
is="dom-if"
if="[[_isConfigParameterSelected(_selectedConfigParameter, 'Bool Button')]]"
>
<div class="device-picker">
<paper-dropdown-menu
label="Config value"
class="flex"
dynamic-align=""
placeholder="{{_loadedConfigValue}}"
>
<paper-listbox
slot="dropdown-content"
selected="{{_selectedConfigValue}}"
>
<template
is="dom-repeat"
items="[[_selectedConfigParameterValues]]"
as="state"
>
<paper-item>[[state]]</paper-item>
</template>
</paper-listbox>
</paper-dropdown-menu>
</div>
</template>
<div class="help-text"><span>[[_configValueHelpText]]</span></div>
<template
is="dom-if"
if="[[_isConfigParameterSelected(_selectedConfigParameter, 'Bool Button Byte Short Int List')]]"
>
<div class="card-actions">
<ha-call-service-button
hass="[[hass]]"
domain="zwave"
service="set_config_parameter"
service-data="[[_computeSetConfigParameterServiceData(_selectedConfigValue)]]"
>
Set Config Parameter
</ha-call-service-button>
</div>
</template>
</ha-card>
</div>
`;
}
static get properties() {
return {
hass: Object,
nodes: Array,
selectedNode: {
type: Number,
observer: "_nodesChanged",
},
config: {
type: Array,
value: () => [],
},
_selectedConfigParameter: {
type: Number,
value: -1,
observer: "_selectedConfigParameterChanged",
},
_configParameterMax: {
type: Number,
value: -1,
},
_configParameterMin: {
type: Number,
value: -1,
},
_configValueHelpText: {
type: String,
value: "",
computed: "_computeConfigValueHelp(_selectedConfigParameter)",
},
_selectedConfigParameterType: {
type: String,
value: "",
},
_selectedConfigValue: {
type: Number,
value: -1,
observer: "_computeSetConfigParameterServiceData",
},
_selectedConfigParameterValues: {
type: Array,
value: () => [],
},
_selectedConfigParameterNumValues: {
type: String,
value: "",
},
_loadedConfigValue: {
type: Number,
value: -1,
},
_wakeupInput: Number,
_wakeupNode: {
type: Boolean,
value: false,
},
};
}
ready() {
super.ready();
this.addEventListener("hass-service-called", (ev) =>
this.serviceCalled(ev)
);
}
serviceCalled(ev) {
if (ev.detail.success) {
setTimeout(() => {
this._refreshConfig(this.selectedNode);
}, 5000);
}
}
_nodesChanged() {
if (!this.nodes) return;
this.setProperties({ _selectedConfigParameter: -1 });
this._wakeupNode =
this.nodes[this.selectedNode].attributes.wake_up_interval === 0 ||
this.nodes[this.selectedNode].attributes.wake_up_interval;
if (this._wakeupNode) {
if (this.nodes[this.selectedNode].attributes.wake_up_interval === 0)
this.setProperties({ _wakeupInput: "" });
else {
this.setProperties({
_wakeupInput: this.nodes[this.selectedNode].attributes
.wake_up_interval,
});
}
}
}
_computeGetWakeupValue(selectedNode) {
if (
this.selectedNode === -1 ||
!this.nodes[selectedNode].attributes.wake_up_interval
)
return "unknown";
return this.nodes[selectedNode].attributes.wake_up_interval;
}
_computeWakeupServiceData(wakeupInput) {
return {
node_id: this.nodes[this.selectedNode].attributes.node_id,
value: wakeupInput,
};
}
_computeConfigValueHelp(selectedConfigParameter) {
if (selectedConfigParameter === -1) return "";
const helpText = this.config[selectedConfigParameter].value.help;
if (!helpText) return ["No helptext available"];
return helpText;
}
_computeSetConfigParameterServiceData(selectedConfigValue) {
if (this.selectedNode === -1 || this._selectedConfigParameter === -1)
return -1;
var valueData = null;
if ("Short Byte Int".includes(this._selectedConfigParameterType)) {
valueData = parseInt(selectedConfigValue, 10);
}
if ("Bool Button List".includes(this._selectedConfigParameterType)) {
valueData = this._selectedConfigParameterValues[selectedConfigValue];
}
return {
node_id: this.nodes[this.selectedNode].attributes.node_id,
parameter: this.config[this._selectedConfigParameter].key,
value: valueData,
};
}
_selectedConfigParameterChanged(selectedConfigParameter) {
if (selectedConfigParameter === -1) return;
this.setProperties({
_selectedConfigValue: -1,
_loadedConfigValue: -1,
_selectedConfigParameterValues: [],
});
this.setProperties({
_selectedConfigParameterType: this.config[selectedConfigParameter].value
.type,
_configParameterMax: this.config[selectedConfigParameter].value.max,
_configParameterMin: this.config[selectedConfigParameter].value.min,
_loadedConfigValue: this.config[selectedConfigParameter].value.data,
_configValueHelpText: this.config[selectedConfigParameter].value.help,
});
if ("Short Byte Int".includes(this._selectedConfigParameterType)) {
this.setProperties({
_selectedConfigParameterNumValues: this.config[selectedConfigParameter]
.value.data_items,
_selectedConfigValue: this._loadedConfigValue,
});
}
if ("Bool Button".includes(this._selectedConfigParameterType)) {
this.setProperties({ _selectedConfigParameterValues: ["True", "False"] });
if (this.config[selectedConfigParameter].value.data) {
this.setProperties({ _loadedConfigValue: "True" });
} else this.setProperties({ _loadedConfigValue: "False" });
}
if ("List".includes(this._selectedConfigParameterType)) {
this.setProperties({
_selectedConfigParameterValues: this.config[selectedConfigParameter]
.value.data_items,
});
}
}
_isConfigParameterSelected(selectedConfigParameter, type) {
if (selectedConfigParameter === -1) return false;
if (this.config[selectedConfigParameter].value.type === type) return true;
if (type.includes(this.config[selectedConfigParameter].value.type))
return true;
return false;
}
_computeSelectCaptionConfigParameter(stateObj) {
return `${stateObj.key}: ${stateObj.value.label}`;
}
async _refreshConfig(selectedNode) {
const configData = [];
const config = await this.hass.callApi(
"GET",
`zwave/config/${this.nodes[selectedNode].attributes.node_id}`
);
Object.keys(config).forEach((key) => {
configData.push({
key: key,
value: config[key],
});
});
this.setProperties({ config: configData });
this._selectedConfigParameterChanged(this._selectedConfigParameter);
}
}
customElements.define("zwave-node-config", ZwaveNodeConfig);

View File

@ -0,0 +1,388 @@
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
PropertyValues,
} from "lit-element";
import { haStyle } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
import "../../../components/buttons/ha-call-service-button";
import "../../../components/ha-card";
import {
ZWaveConfigItem,
ZWaveNode,
ZWaveConfigServiceData,
fetchNodeConfig,
} from "../../../data/zwave";
@customElement("zwave-node-config")
export class ZwaveNodeConfig extends LitElement {
@property() public hass!: HomeAssistant;
@property() public nodes: ZWaveNode[] = [];
@property() public config: ZWaveConfigItem[] = [];
@property() public selectedNode: number = -1;
@property() private _configItem?: ZWaveConfigItem;
@property() private _wakeupInput: number = -1;
@property() private _selectedConfigParameter: number = -1;
@property() private _selectedConfigValue: number | string = -1;
protected render(): TemplateResult | void {
return html`
<div class="content">
<ha-card
.header=${this.hass!.localize(
"ui.panel.config.zwave.node_config.header"
)}
>
${"wake_up_interval" in this.nodes[this.selectedNode].attributes
? html`
<div class="card-actions">
<paper-input
.floatLabel="${this.hass!.localize(
"ui.panel.config.zwave.common.wakeup_interval"
)}"
type="number"
.value=${this._wakeupInput !== -1
? this._wakeupInput
: this.hass!.localize(
"ui.panel.config.zwave.common.unknown"
)}
@value-changed=${this._onWakeupIntervalChanged}
.placeholder=${this.nodes[this.selectedNode].attributes
.wake_up_interval
? this.nodes[this.selectedNode].attributes
.wake_up_interval
: this.hass!.localize(
"ui.panel.config.zwave.common.unknown"
)}
>
<div suffix>
${this.hass!.localize(
"ui.panel.config.zwave.node_config.seconds"
)}
</div>
</paper-input>
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="set_wakeup"
.serviceData=${this._computeWakeupServiceData(
this._wakeupInput
)}
>
${this.hass!.localize(
"ui.panel.config.zwave.node_config.set_wakeup"
)}
</ha-call-service-button>
</div>
`
: ""}
<div class="device-picker">
<paper-dropdown-menu
.label=${this.hass!.localize(
"ui.panel.config.zwave.node_config.config_parameter"
)}
dynamic-align
class="flex"
>
<paper-listbox
slot="dropdown-content"
.selected=${this._selectedConfigParameter}
@iron-select=${this._selectedConfigParameterChanged}
>
${this.config.map(
(state) => html`
<paper-item>
${state.key}: ${state.value.label}
</paper-item>
`
)}
</paper-listbox>
</paper-dropdown-menu>
</div>
${this._configItem
? html`
${this._configItem.value.type === "List"
? html`
<div class="device-picker">
<paper-dropdown-menu
.label=${this.hass!.localize(
"ui.panel.config.zwave.node_config.config_value"
)}
dynamic-align
class="flex"
.placeholder=${this._configItem.value.data}
>
<paper-listbox
slot="dropdown-content"
.selected=${this._configItem.value.data}
@iron-select=${this._configValueSelectChanged}
>
${this._configItem.value.data_items.map(
(state) => html`
<paper-item>${state}</paper-item>
`
)}
</paper-listbox>
</paper-dropdown-menu>
</div>
`
: ""}
${["Byte", "Short", "Int"].includes(this._configItem.value.type)
? html`
<div class="card-actions">
<paper-input
.label=${this._configItem.value.data_items}
type="number"
.value=${this._configItem.value.data}
.max=${this._configItem.value.max}
.min=${this._configItem.value.min}
@value-changed=${this._configValueInputChanged}
>
</paper-input>
</div>
`
: ""}
${["Bool", "Button"].includes(this._configItem.value.type)
? html`
<div class="device-picker">
<paper-dropdown-menu
.label=${this.hass!.localize(
"ui.panel.config.zwave.node_config.config_value"
)}
class="flex"
dynamic-align
.placeholder=${this._configItem.value.data}
>
<paper-listbox
slot="dropdown-content"
.selected=${this._configItem.value.data}
@iron-select=${this._configValueSelectChanged}
>
<paper-item>
${this.hass!.localize(
"ui.panel.config.zwave.node_config.true"
)}
</paper-item>
<paper-item>
${this.hass!.localize(
"ui.panel.config.zwave.node_config.false"
)}
</paper-item>
</paper-listbox>
</paper-dropdown-menu>
</div>
`
: ""}
<div class="help-text">
<span>${this._configItem.value.help}</span>
</div>
${["Bool", "Button", "Byte", "Short", "Int", "List"].includes(
this._configItem.value.type
)
? html`
<div class="card-actions">
<ha-call-service-button
.hass=${this.hass}
domain="zwave"
service="set_config_parameter"
.serviceData=${this._computeSetConfigParameterServiceData()}
>
${this.hass!.localize(
"ui.panel.config.zwave.node_config.set_config_parameter"
)}
</ha-call-service-button>
</div>
`
: ""}
`
: ""}
</ha-card>
</div>
`;
}
static get styles(): CSSResult[] {
return [
haStyle,
css`
.content {
margin-top: 24px;
}
ha-card {
margin: 0 auto;
max-width: 600px;
}
.device-picker {
@apply --layout-horizontal;
@apply --layout-center-center;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-ms-flex-direction: row;
-webkit-flex-direction: row;
flex-direction: row;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 24px;
}
.help-text {
padding-left: 24px;
padding-right: 24px;
}
.flex {
-ms-flex: 1 1 0.000000001px;
-webkit-flex: 1;
flex: 1;
-webkit-flex-basis: 0.000000001px;
flex-basis: 0.000000001px;
}
`,
];
}
protected firstUpdated(changedProps: PropertyValues): void {
super.firstUpdated(changedProps);
this.addEventListener("hass-service-called", (ev) =>
this.serviceCalled(ev)
);
}
protected updated(changedProps: PropertyValues): void {
super.updated(changedProps);
if (changedProps.has("selectedNode")) {
this._nodesChanged();
}
}
private serviceCalled(ev): void {
if (ev.detail.success) {
setTimeout(() => {
this._refreshConfig(this.selectedNode);
}, 5000);
}
}
private _nodesChanged(): void {
if (!this.nodes) {
return;
}
this._configItem = undefined;
this._wakeupInput = this.nodes[this.selectedNode].attributes.hasOwnProperty(
"wake_up_interval"
)
? this.nodes[this.selectedNode].attributes.wake_up_interval!
: -1;
}
private _onWakeupIntervalChanged(value: ChangeEvent): void {
this._wakeupInput = value.detail!.value;
}
private _computeWakeupServiceData(wakeupInput: number) {
return {
node_id: this.nodes[this.selectedNode].attributes.node_id,
value: wakeupInput,
};
}
private _computeSetConfigParameterServiceData():
| ZWaveConfigServiceData
| boolean {
if (this.selectedNode === -1 || typeof this._configItem === "undefined") {
return false;
}
let valueData: number | string = "";
if (["Short", "Byte", "Int"].includes(this._configItem!.value.type)) {
valueData =
typeof this._selectedConfigValue === "string"
? parseInt(this._selectedConfigValue, 10)
: this._selectedConfigValue;
}
if (["Bool", "Button", "List"].includes(this._configItem!.value.type)) {
valueData = this._selectedConfigValue;
}
return {
node_id: this.nodes[this.selectedNode].attributes.node_id,
parameter: this._configItem.key,
value: valueData,
};
}
private _selectedConfigParameterChanged(event: ItemSelectedEvent): void {
if (event.target!.selected === -1) {
return;
}
this._selectedConfigParameter = event.target!.selected;
this._configItem = this.config[event.target!.selected];
}
private _configValueSelectChanged(event: ItemSelectedEvent): void {
if (event.target!.selected === -1) {
return;
}
this._selectedConfigValue = event.target!.selectedItem.textContent;
}
private _configValueInputChanged(value: ChangeEvent): void {
this._selectedConfigValue = value.detail!.value;
}
private async _refreshConfig(selectedNode): Promise<void> {
const configData: ZWaveConfigItem[] = [];
const config = await fetchNodeConfig(
this.hass,
this.nodes[selectedNode].attributes.node_id
);
Object.keys(config).forEach((key) => {
configData.push({
key: parseInt(key, 10),
value: config[key],
});
});
this.config = configData;
this._configItem = this.config[this._selectedConfigParameter];
}
}
export interface ChangeEvent {
detail?: {
value?: any;
};
target?: EventTarget;
}
export interface PickerTarget extends EventTarget {
selected: number;
selectedItem?: any;
}
export interface ItemSelectedEvent {
target?: PickerTarget;
}
declare global {
interface HTMLElementTagNameMap {
"zwave-node-config": ZwaveNodeConfig;
}
}

View File

@ -169,7 +169,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
: ""}
</div>
<div class="modes">
${stateObj.attributes.hvac_modes
${(stateObj.attributes.hvac_modes || [])
.concat()
.sort(compareClimateHvacModes)
.map((modeItem) => this._renderIcon(modeItem, mode))}
@ -288,7 +288,11 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
let sliderValue: string | number | null;
let uiValue: string;
if (
if (stateObj.state === "unavailable") {
sliderType = "min-range";
sliderValue = null;
uiValue = this.hass!.localize("state.default.unavailable");
} else if (
stateObj.attributes.target_temp_low &&
stateObj.attributes.target_temp_high
) {

View File

@ -93,6 +93,7 @@ export class HuiEditView extends LitElement {
case "tab-settings":
content = html`
<hui-view-editor
.isNew=${this.viewIndex === undefined}
.hass="${this.hass}"
.config="${this._config}"
@view-config-changed="${this._viewConfigChanged}"

View File

@ -15,6 +15,7 @@ import { configElementStyle } from "../config-elements/config-elements-style";
import "../../components/hui-theme-select-editor";
import { LovelaceViewConfig } from "../../../../data/lovelace";
import { slugify } from "../../../../common/string/slugify";
declare global {
interface HASSDomEvents {
@ -26,9 +27,10 @@ declare global {
@customElement("hui-view-editor")
export class HuiViewEditor extends LitElement {
@property() public hass?: HomeAssistant;
@property() private _config?: LovelaceViewConfig;
@property() public hass!: HomeAssistant;
@property() public isNew!: boolean;
@property() private _config!: LovelaceViewConfig;
private _suggestedPath = false;
get _path(): string {
if (!this._config) {
@ -79,32 +81,33 @@ export class HuiViewEditor extends LitElement {
<div class="card-config">
<paper-input
label="Title"
.value="${this._title}"
.configValue="${"title"}"
@value-changed="${this._valueChanged}"
.value=${this._title}
.configValue=${"title"}
@value-changed=${this._valueChanged}
@blur=${this._handleTitleBlur}
></paper-input>
<paper-input
label="Icon"
.value="${this._icon}"
.configValue="${"icon"}"
@value-changed="${this._valueChanged}"
.value=${this._icon}
.configValue=${"icon"}
@value-changed=${this._valueChanged}
></paper-input>
<paper-input
label="URL Path"
.value="${this._path}"
.configValue="${"path"}"
@value-changed="${this._valueChanged}"
.value=${this._path}
.configValue=${"path"}
@value-changed=${this._valueChanged}
></paper-input>
<hui-theme-select-editor
.hass="${this.hass}"
.value="${this._theme}"
.configValue="${"theme"}"
@theme-changed="${this._valueChanged}"
.hass=${this.hass}
.value=${this._theme}
.configValue=${"theme"}
@theme-changed=${this._valueChanged}
></hui-theme-select-editor>
<paper-toggle-button
?checked="${this._panel !== false}"
.configValue="${"panel"}"
@change="${this._valueChanged}"
?checked=${this._panel !== false}
.configValue=${"panel"}
@change=${this._valueChanged}
>Panel Mode?</paper-toggle-button
>
</div>
@ -112,10 +115,6 @@ export class HuiViewEditor extends LitElement {
}
private _valueChanged(ev: Event): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.currentTarget! as EditorTarget;
if (this[`_${target.configValue}`] === target.value) {
@ -134,6 +133,20 @@ export class HuiViewEditor extends LitElement {
fireEvent(this, "view-config-changed", { config: newConfig });
}
private _handleTitleBlur(ev) {
if (
!this.isNew ||
this._suggestedPath ||
this._config.path ||
!ev.currentTarget.value
) {
return;
}
const config = { ...this._config, path: slugify(ev.currentTarget.value) };
fireEvent(this, "view-config-changed", { config });
}
}
declare global {

View File

@ -49,8 +49,7 @@ class LovelacePanel extends LitElement {
private mqls?: MediaQueryList[];
private _ignoreNextUpdateEventBecauseOfSave = false;
private _ignoreUpdateUntilTime: number | undefined;
private _ignoreNextUpdateEvent = false;
constructor() {
super();
@ -185,14 +184,8 @@ class LovelacePanel extends LitElement {
}
private _lovelaceChanged() {
if (
this._ignoreUpdateUntilTime &&
new Date().getTime() < this._ignoreUpdateUntilTime
) {
return;
}
if (this._ignoreNextUpdateEventBecauseOfSave) {
this._ignoreNextUpdateEventBecauseOfSave = false;
if (this._ignoreNextUpdateEvent) {
this._ignoreNextUpdateEvent = false;
return;
}
showToast(this, {
@ -222,10 +215,10 @@ class LovelacePanel extends LitElement {
llWindow.llConfProm = undefined;
} else {
// Refreshing a YAML config can trigger an update event. We will ignore
// all update events for a second after we refresh, as we already have
// the latest config in that case.
// all update events while fetching the config and for 2 seconds after the cnofig is back.
// We ignore because we already have the latest config.
if (this.lovelace && this.lovelace.mode === "yaml") {
this._ignoreUpdateUntilTime = new Date().getTime() + 1000;
this._ignoreNextUpdateEvent = true;
}
confProm = fetchConfig(this.hass!.connection, forceDiskRefresh);
@ -243,6 +236,13 @@ class LovelacePanel extends LitElement {
}
conf = await generateLovelaceConfigFromHass(this.hass!);
confMode = "generated";
} finally {
// Ignore updates for another 2 seconds.
if (this.lovelace && this.lovelace.mode === "yaml") {
setTimeout(() => {
this._ignoreNextUpdateEvent = false;
}, 2000);
}
}
this._state = "loaded";
@ -279,7 +279,7 @@ class LovelacePanel extends LitElement {
config: newConfig,
mode: "storage",
});
this._ignoreNextUpdateEventBecauseOfSave = true;
this._ignoreNextUpdateEvent = true;
await saveConfig(this.hass!, newConfig);
} catch (err) {
// tslint:disable-next-line

View File

@ -932,7 +932,9 @@
"common": {
"value": "Value",
"instance": "Instance",
"index": "Index"
"index": "Index",
"unknown": "unknown",
"wakeup_interval": "Wakeup Interval"
},
"network_management": {
"header": "Z-Wave Network Management",
@ -946,6 +948,16 @@
"network_started_note_some_queried": "Awake nodes have been queried. Sleeping nodes will be queried when they wake.",
"network_started_note_all_queried": "All nodes have been queried."
},
"node_config": {
"header": "Node Config Options",
"seconds": "seconds",
"set_wakeup": "Set Wakeup Interval",
"config_parameter": "Config Parameter",
"config_value": "Config Value",
"true": "True",
"false": "False",
"set_config_parameter": "Set Config Parameter"
},
"values": {
"header": "Node Values"
},

View File

@ -747,6 +747,33 @@
"device_tracker_picked": "Seguint dispositiu",
"device_tracker_pick": "Tria un dispositiu per fer-li el seguiment"
}
},
"server_control": {
"caption": "Control del servidor",
"description": "Reinicia o atura el servidor de Home Assistant",
"section": {
"validation": {
"heading": "Validació de la configuració",
"introduction": "Valida la configuració si recentment has fet algun canvi a la configuració i vols assegurar-te de que sigui vàlida.",
"check_config": "Comprova la configuració",
"valid": "Configuració vàlida!",
"invalid": "Configuració invàlida"
},
"reloading": {
"heading": "Tornant a carregar configuració",
"introduction": "Algunes parts de la configuració de Home Assistant es poden recarregar sense necessitat de reiniciar. Els botons de sota esborraran la configuració antiga i en carregaran la nova.",
"core": "Actualitza el nucli",
"group": "Actualitza grups",
"automation": "Actualitza automatismes",
"script": "Actualitza programes"
},
"server_management": {
"heading": "Gestió del servidor",
"introduction": "Controla el servidor de Home Assistant... des de Home Assistant.",
"restart": "Reinicia",
"stop": "Atura"
}
}
}
},
"profile": {

View File

@ -349,7 +349,7 @@
"introduction": "Her er det muligt at konfigurere dine komponenter og Home Assistant. Ikke alt er muligt at konfigurere fra brugergrænsefladen endnu, men vi arbejder på det.",
"core": {
"caption": "Generelt",
"description": "Valider din konfigurationsfil og kontroller serveren",
"description": "Valider din konfigurationsfil og administrer serveren",
"section": {
"core": {
"header": "Konfiguration og server kontrol",
@ -747,6 +747,33 @@
"device_tracker_picked": "Spor enhed",
"device_tracker_pick": "Vælg en enhed, der skal spores"
}
},
"server_control": {
"caption": "Serveradministration",
"description": "Genstart og stop Home Assistant serveren",
"section": {
"validation": {
"heading": "Validering af konfiguration",
"introduction": "Valider din konfiguration, hvis du for nylig har foretaget nogle ændringer i din konfiguration og vil sikre dig, at den er gyldig",
"check_config": "Tjek konfiguration",
"valid": "Konfiguration gyldig!",
"invalid": "Konfiguration ugyldig"
},
"reloading": {
"heading": "Genindlæser konfiguration",
"introduction": "Nogle dele af Home Assistant kan genindlæses uden en genstart. Tryk på genindlæs for at aflæse den nuværende konfiguration og indlæse den nye.",
"core": "Genindlæs system",
"group": "Genindlæs grupper",
"automation": "Genindlæs automatiseringer",
"script": "Genindlæs scripts"
},
"server_management": {
"heading": "Serveradministration",
"introduction": "Administrer din Home Assistant server... fra Home Assistant.",
"restart": "Genstart",
"stop": "Stop"
}
}
}
},
"profile": {

View File

@ -747,6 +747,33 @@
"device_tracker_picked": "Verfolge Gerät",
"device_tracker_pick": "Wähle zu verfolgendes Gerät"
}
},
"server_control": {
"caption": "Serversteuerung",
"description": "Neustarten und Stoppen des Home Assistant-Servers",
"section": {
"validation": {
"heading": "Konfiguration überprüfen",
"introduction": "Überprüfe deine Konfiguration wenn du kürzlich Änderungen vorgenommen hast und sicherstellen möchtest, dass alle Änderungen gültig sind",
"check_config": "Konfiguration prüfen",
"valid": "Konfiguration in Ordnung",
"invalid": "Konfiguration ungültig"
},
"reloading": {
"heading": "Konfiguration neu laden",
"introduction": "Einige Komponenten von Home Assistant können ohne einen Neustart neu geladen werden. \"Neu laden\" entlädt dabei die aktuelle Konfiguration und lädt die Neue.",
"core": "Hauptsystem neu laden",
"group": "Gruppen neu laden",
"automation": "Automatisierungen neu laden",
"script": "Skripte neu laden"
},
"server_management": {
"heading": "Serververwaltung",
"introduction": "Verwalte Home Assistant… von Home Assistant aus.",
"restart": "Neu starten",
"stop": "Stoppen"
}
}
}
},
"profile": {

View File

@ -747,6 +747,33 @@
"device_tracker_picked": "Rastrear dispositivo",
"device_tracker_pick": "Seleccionar dispositivo para rastrear"
}
},
"server_control": {
"caption": "Control del servidor",
"description": "Reinicia y detiene el servidor de Home Assistant",
"section": {
"validation": {
"heading": "Validación de la configuración",
"introduction": "Valida tu configuración si has realizado cambios recientemente y quieres asegurarte de que son correctos",
"check_config": "Verificar la configuración",
"valid": "¡Configuración valida!",
"invalid": "Configuración no válida"
},
"reloading": {
"heading": "Recargando la configuración",
"introduction": "Algunas partes de Home Assistant pueden recargarse sin necesidad de reiniciar. Al pulsar en recargar se descartará la configuración actual y se cargará la nueva.",
"core": "Recargar núcleo",
"group": "Recargar grupos",
"automation": "Recargar automatizaciones",
"script": "Recargar los scripts"
},
"server_management": {
"heading": "Gestión del servidor",
"introduction": "Controla tu servidor de Home Assistant ... desde Home Assistant.",
"restart": "Reiniciar",
"stop": "Detener"
}
}
}
},
"profile": {

View File

@ -360,8 +360,8 @@
"elevation_meters": "metriä",
"time_zone": "Aikavyöhyke",
"unit_system": "Yksikköjärjestelmä",
"unit_system_imperial": "Imperial",
"unit_system_metric": "Metrinen",
"unit_system_imperial": "Brittiläinen yksikköjärjestelmä",
"unit_system_metric": "Kansainvälinen yksikköjärjestelmä",
"imperial_example": "Fahrenheit, paunaa",
"metric_example": "Celsius, kilogrammat",
"save_button": "Tallenna"

View File

@ -128,7 +128,7 @@
},
"climate": {
"off": "Off",
"on": "On",
"on": "Marche",
"heat": "Chauffe",
"cool": "Frais",
"idle": "Inactif",
@ -160,8 +160,8 @@
"not_home": "Absent"
},
"fan": {
"off": "Off",
"on": "On"
"off": "Arrêt",
"on": "Marche"
},
"group": {
"off": "Off",
@ -179,20 +179,20 @@
"problem": "Problème"
},
"input_boolean": {
"off": "Off",
"on": "On"
"off": "Arrêt",
"on": "Marche"
},
"light": {
"off": "Off",
"on": "On"
"off": "Éteinte",
"on": "Allumée"
},
"lock": {
"locked": "Verrouillé",
"unlocked": "Déverrouillé"
},
"media_player": {
"off": "Off",
"on": "On",
"off": "Arrêt",
"on": "Marche",
"playing": "Lecture en cours",
"paused": "En pause",
"idle": "En veille",
@ -203,7 +203,7 @@
"problem": "Problème"
},
"remote": {
"off": "Off",
"off": "Arrêt",
"on": "On"
},
"scene": {
@ -265,7 +265,7 @@
},
"timer": {
"active": "actif",
"idle": "En veille",
"idle": "en veille",
"paused": "en pause"
},
"person": {
@ -290,7 +290,7 @@
"arming": "Activer",
"disarming": "Désarmement",
"triggered": "Déclenchée",
"armed_custom_bypass": "Activée"
"armed_custom_bypass": "Armée"
},
"device_tracker": {
"home": "Maison",
@ -320,7 +320,7 @@
"title": "Événements"
},
"templates": {
"title": "Templates"
"title": "Gabarit"
},
"mqtt": {
"title": "MQTT"
@ -352,7 +352,7 @@
"description": "Validez votre fichier de configuration et contrôlez le serveur",
"section": {
"core": {
"header": "Configuration et contrôle du serveur",
"header": "Configuration générale",
"introduction": "Changer votre configuration peut être un processus fastidieux. Nous le savons. Cette section va essayer de vous rendre la vie un peu plus facile.",
"core_config": {
"edit_requires_storage": "L'éditeur est désactivé car la configuration est stockée dans configuration.yaml.",
@ -532,8 +532,8 @@
"sunset": "Coucher du soleil"
},
"template": {
"label": "Template",
"value_template": "Contenu du template"
"label": "Gabarit",
"value_template": "Valeur du gabarit"
},
"time": {
"label": "Heure",
@ -555,7 +555,7 @@
"duplicate": "Dupliquer",
"delete": "Supprimer",
"delete_confirm": "Voulez-vous vraiment effacer ?",
"unsupported_action": "Action non supportée : {action}",
"unsupported_action": "Action non supportée : {action}",
"type_select": "Type d'action",
"type": {
"service": {
@ -593,20 +593,34 @@
"zwave": {
"caption": "Z-Wave",
"description": "Gérez votre réseau Z-Wave",
"network_management": {
"header": "Gestion de réseau Z-Wave"
},
"network_status": {
"network_stopped": "Réseau Z-Wave arrêté",
"network_starting": "Démarrage du réseau Z-Wave...",
"network_starting_note": "Ceci peut prendre un certain temps en fonction du débit de votre réseau.",
"network_started": "Le réseau Z-Wave a été démarré"
"network_started": "Le réseau Z-Wave a été démarré",
"network_started_note_all_queried": "Tous les nœuds ont été interrogés."
},
"services": {
"start_network": "Démarrer le réseau",
"stop_network": "Arrêter le réseau",
"heal_network": "Soigner le réseau",
"test_network": "Tester le réseau",
"save_config": "Enregistrer la configuration",
"add_node_secure": "Ajouter un nœud sécurisé",
"add_node": "Ajouter un nœud",
"remove_node": "Supprimer un nœud"
"remove_node": "Supprimer un nœud",
"cancel_command": "Annuler la commande"
},
"common": {
"value": "Valeur",
"instance": "Instance",
"index": "Indice"
},
"values": {
"header": "Valeurs des nœuds"
}
},
"users": {
@ -730,6 +744,28 @@
"device_tracker_picked": "Appareil suivi",
"device_tracker_pick": "Choisissez le périphérique à suivre"
}
},
"server_control": {
"section": {
"validation": {
"heading": "Validation de la configuration",
"check_config": "Vérifiez la configuration",
"valid": "Configuration valide !",
"invalid": "Configuration invalide"
},
"reloading": {
"heading": "Rechargement de la configuration",
"core": "Recharger le noyau",
"group": "Recharger les groupes",
"automation": "Recharger les automatisations",
"script": "Recharger les scripts"
},
"server_management": {
"heading": "Gestion du serveur",
"restart": "Redémarrer",
"stop": "Arrêter"
}
}
}
},
"profile": {
@ -801,7 +837,10 @@
"close": "Fermer",
"submit": "Envoyer"
},
"logout": "Déconnexion"
"logout": "Déconnexion",
"force_narrow": {
"header": "Toujours cacher la barre latérale"
}
},
"page-authorize": {
"initializing": "Initialisation",
@ -1218,7 +1257,7 @@
"dialogs": {
"more_info_settings": {
"save": "Sauvegarder",
"name": "Nom",
"name": "Surcharge du nom",
"entity_id": "ID de l'entité"
},
"more_info_control": {
@ -1313,6 +1352,14 @@
"home": "Accueil",
"sleep": "Veille",
"activity": "Activité"
},
"hvac_action": {
"off": "Éteint",
"heating": "Chauffage",
"cooling": "Refroidissement",
"drying": "Séchage",
"idle": "Inactif",
"fan": "Ventilateur"
}
}
},

View File

@ -320,7 +320,7 @@
"title": "Hendelser"
},
"templates": {
"title": "Maler"
"title": "Mal"
},
"mqtt": {
"title": "MQTT"
@ -349,10 +349,10 @@
"introduction": "Her er det mulig å konfigurere dine komponenter og Home Assistant. Ikke alt er mulig å konfigurere fra brukergrensesnittet enda, men vi jobber med det.",
"core": {
"caption": "Generelt",
"description": "Valider konfigurasjonsfilen din og kontroller serveren",
"description": "Endre den generelle konfigurasjonen for Home Assistant",
"section": {
"core": {
"header": "Konfigurasjon og serverkontroll",
"header": "Generell konfigurasjon",
"introduction": "Endring av konfigurasjonen kan være en slitsom prosess, det vet vi. Denne delen vil forsøke å gjøre livet ditt litt lettere.",
"core_config": {
"edit_requires_storage": "Redigering deaktivert da konfigurasjonen er lagret i configuration.yaml.",
@ -747,6 +747,33 @@
"device_tracker_picked": "Spor enhet",
"device_tracker_pick": "Velg en enhet å spore"
}
},
"server_control": {
"caption": "Server-kontroll",
"description": "Start på nytt og stopp Home Assistant-serveren",
"section": {
"validation": {
"heading": "Validering av konfigurasjon",
"introduction": "Valider konfigurasjonen hvis du nylig har gjort endringer i konfigurasjonen og vil forsikre deg om at det hele er gyldig",
"check_config": "Sjekk konfigurasjonen",
"valid": "Gyldig konfigurasjon",
"invalid": "Ugyldig konfigurasjon"
},
"reloading": {
"heading": "Konfigurasjon lastes på nytt",
"introduction": "Noen deler av Home Assistant kan laste inn uten å kreve omstart. Hvis du trykker last på nytt, vil du bytte den nåværende konfigurasjonen med den nye.",
"core": "Last inn kjernen på nytt",
"group": "Last inn grupper på nytt",
"automation": "Last inn automatiseringer på nytt",
"script": "Last inn skript på nytt"
},
"server_management": {
"heading": "Serveradministrasjon",
"introduction": "Kontroller din Home Assistant server... fra Home Assistant.",
"restart": "Omstart",
"stop": "Stopp"
}
}
}
},
"profile": {
@ -1329,7 +1356,7 @@
"none": "Ingen",
"eco": "Øko",
"away": "Borte",
"boost": "Turbo",
"boost": "Øke",
"comfort": "Komfort",
"home": "Hjem",
"sleep": "Sove",

View File

@ -349,7 +349,7 @@
"introduction": "Hier kun je je componenten en Home Assistant configureren. Het is nog niet mogelijk om alles te configureren vanuit de interface, maar we werken er aan.",
"core": {
"caption": "Algemeen",
"description": "Valideer je configuratiebestand en beheer de server",
"description": "Wijzig je algemene Home Assistant configuratie",
"section": {
"core": {
"header": "Configuratie en serverbeheer",
@ -747,6 +747,33 @@
"device_tracker_picked": "Volg apparaat",
"device_tracker_pick": "Kies apparaat om te volgen"
}
},
"server_control": {
"caption": "Serverbeheer",
"description": "De Home Assistant-server opnieuw opstarten en stoppen",
"section": {
"validation": {
"heading": "Valideer configuratie",
"introduction": "Controleer je configuratie als je onlangs wijzigingen hebt aangebracht en zeker wilt weten dat ze geldig zijn",
"check_config": "Controleer configuratie",
"valid": "Geldige configuratie!",
"invalid": "Ongeldige configuratie"
},
"reloading": {
"heading": "Configuratie herladen",
"introduction": "Sommige delen van Home Assistant kunnen opnieuw worden geladen zonder dat een herstart vereist is. Als je herladen gebruikt, wordt de huidige configuratie leeggemaakt en wordt de nieuwe geladen.",
"core": "Herlaad kern",
"group": "Herlaad groepen",
"automation": "Herlaad automatiseringen",
"script": "Herlaad scripts"
},
"server_management": {
"heading": "Serverbeheer",
"introduction": "Beheer je Home Assistant-server ... vanuit Home Assistant.",
"restart": "Herstarten",
"stop": "Stop"
}
}
}
},
"profile": {

View File

@ -747,6 +747,33 @@
"device_tracker_picked": "Śledź urządzenie",
"device_tracker_pick": "Wybierz urządzenie do śledzenia"
}
},
"server_control": {
"caption": "Kontrola serwera",
"description": "Uruchom ponownie i zatrzymaj serwer Home Assistant",
"section": {
"validation": {
"heading": "Sprawdzanie konfiguracji",
"introduction": "Jeśli ostatnio wprowadzano zmiany w konfiguracji sprawdź jej poprawność",
"check_config": "Sprawdź konfigurację",
"valid": "Konfiguracja prawidłowa!",
"invalid": "Konfiguracja nieprawidłowa"
},
"reloading": {
"heading": "Przeładowanie konfiguracji",
"introduction": "Niektóre części Home Assistant'a można przeładować bez konieczności ponownego uruchomienia. Kliknięcie przeładuj spowoduje ponowne wczytanie konfiguracji.",
"core": "Przeładuj rdzeń",
"group": "Przeładuj grupy",
"automation": "Przeładuj automatyzacje",
"script": "Przeładuj skrypty"
},
"server_management": {
"heading": "Zarządzanie serwerem",
"introduction": "Kontroluj swój serwer Home Assistant… z Home Assistant.",
"restart": "Uruchom ponownie",
"stop": "Zatrzymaj"
}
}
}
},
"profile": {
@ -1138,10 +1165,10 @@
"alarm_control_panel": {
"code": "Kod",
"clear_code": "Wyczyść",
"disarm": "Rozbrojenie",
"arm_home": "Uzbrojenie (w domu)",
"arm_away": "Uzbrojenie (nieobecny)",
"arm_night": "Uzbrojenie (noc)",
"disarm": "rozbrojenie",
"arm_home": "uzbrojenie (w domu)",
"arm_away": "uzbrojenie (nieobecny)",
"arm_night": "uzbrojenie (noc)",
"armed_custom_bypass": "Uzbrój (częściowo)",
"arm_custom_bypass": "Niestandardowy bypass"
},

View File

@ -349,10 +349,10 @@
"introduction": "Здесь можно настроить Home Assistant. Пока что не все настройки доступны из интерфейса, но мы работаем над этим.",
"core": {
"caption": "Общие",
"description": "Проверяйте Ваш файл конфигурации и управляйте сервером",
"description": "Управляйте основными настройками Home Assistant",
"section": {
"core": {
"header": "Конфигурация и управление сервером",
"header": "Общие настройки",
"introduction": "Изменение конфигурации может быть утомительным процессом. Мы знаем. Этот раздел может немного упростить эту задачу.",
"core_config": {
"edit_requires_storage": "Редактор отключен, поскольку конфигурация уже хранится в файле configuration.yaml.",
@ -747,6 +747,33 @@
"device_tracker_picked": "Устройство для отслеживания",
"device_tracker_pick": "Выберите устройство для отслеживания"
}
},
"server_control": {
"caption": "Управление сервером",
"description": "Перезапуск или остановка Home Assistant",
"section": {
"validation": {
"heading": "Проверка конфигурации",
"introduction": "Проверьте файлы конфигурации, если Вы внесли в них изменения",
"check_config": "Начать проверку",
"valid": "Конфигурация выполнена верно",
"invalid": "Ошибка в конфигурации"
},
"reloading": {
"heading": "Перезагрузка конфигурации",
"introduction": "Некоторые компоненты Home Assistant можно перезагрузить без необходимости перезапуска всей системы. Перезагрузка выгружает текущую конфигурацию и загружает новую.",
"core": "Перезагрузить ядро",
"group": "Перезагрузить группы",
"automation": "Перезагрузить автоматизации",
"script": "Перезагрузить скрипты"
},
"server_management": {
"heading": "Управление сервером",
"introduction": "Управляйте Вашим сервером Home Assistant... из Home Assistant",
"restart": "Перезапустить",
"stop": "Остановить"
}
}
}
},
"profile": {

View File

@ -747,6 +747,33 @@
"device_tracker_picked": "Sledi Napravi",
"device_tracker_pick": "Izberite napravo za sledenje"
}
},
"server_control": {
"caption": "Nadzor strežnika",
"description": "Znova zaženite in ustavite strežnik Home Assistant",
"section": {
"validation": {
"heading": "Preverjanje konfiguracije",
"introduction": "Potrdite svojo konfiguracijo, če ste nedavno spremenili svojo konfiguracijo in se prepričajte, da je vse veljavno",
"check_config": "Preverite nastavitve",
"valid": "Konfiguracija veljavna!",
"invalid": "Konfiguracija ni veljavna"
},
"reloading": {
"heading": "Ponovno nalaganje konfiguracije",
"introduction": "Nekateri deli Home Assistanta se lahko znova naložijo brez potrebe po ponovnem zagonu. S pritiskom na \"ponovno naloži\" se bo naložila nova konfiguracija",
"core": "Ponovno naloži jedro",
"group": "Ponovno naloži skupine",
"automation": "Ponovno naloži avtomatizacije",
"script": "Ponovno naloži skripte"
},
"server_management": {
"heading": "Upravljanje strežnika",
"introduction": "Nadzirajte strežnik Home Assistant ... iz Home Assistant-a",
"restart": "Ponovni zagon",
"stop": "Ustavi"
}
}
}
},
"profile": {

View File

@ -349,10 +349,10 @@
"introduction": "此處為 Home Assistant 和元件相關配置區,目前尚未支援透過 UI 進行所有設定,我們正在努力改進中。",
"core": {
"caption": "一般設定",
"description": "驗證設定內容及服務器控制",
"description": "變更 Home Assistant 一般設定",
"section": {
"core": {
"header": "設定和服務器控制",
"header": "一般設定",
"introduction": "更改設定常是個惱人過程。此區域將盡可能協助您,讓事情變得更輕鬆一些。",
"core_config": {
"edit_requires_storage": "由於 configuration.yaml 內已儲存設定,編輯功能已關閉。",
@ -747,6 +747,33 @@
"device_tracker_picked": "追蹤設備",
"device_tracker_pick": "選擇追蹤設備"
}
},
"server_control": {
"caption": "伺服器控制",
"description": "重啟與停止 Home Assistant 伺服器",
"section": {
"validation": {
"heading": "設定驗證",
"introduction": "如果您對設定進行了一些更改、並且想確保設定有無錯誤,可以選擇驗證設定內容。",
"check_config": "檢查設定內容",
"valid": "設定檔內容檢查正確",
"invalid": "設定無效"
},
"reloading": {
"heading": "正在重新載入設定",
"introduction": "Home Assistant 中部分設定無須重啟即可重新載入生效。點選重新載入按鈕,即可重新載入最新設定。",
"core": "重新載入核心設定",
"group": "重新載入群組",
"automation": "重新載入自動化",
"script": "重新載入腳本"
},
"server_management": {
"heading": "服務器管理",
"introduction": "由 Home Assistant控制 Home Assistant 伺服器。",
"restart": "重啟",
"stop": "停止"
}
}
}
},
"profile": {