mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 19:56:42 +00:00
Merge pull request #6198 from home-assistant/dev
This commit is contained in:
commit
79a6dacd2f
@ -192,6 +192,8 @@ export class HcMain extends HassElement {
|
||||
this._handleNewLovelaceConfig(lovelaceConfig)
|
||||
);
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.log("Error fetching Lovelace configuration", err, msg);
|
||||
// Generate a Lovelace config.
|
||||
this._unsubLovelace = () => undefined;
|
||||
await this._generateLovelaceConfig();
|
||||
|
@ -14,7 +14,9 @@ import {
|
||||
createHassioSession,
|
||||
fetchHassioHomeAssistantInfo,
|
||||
fetchHassioSupervisorInfo,
|
||||
fetchHassioInfo,
|
||||
HassioHomeAssistantInfo,
|
||||
HassioInfo,
|
||||
HassioPanelInfo,
|
||||
HassioSupervisorInfo,
|
||||
} from "../../src/data/hassio/supervisor";
|
||||
@ -75,6 +77,8 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
||||
|
||||
@property() private _hostInfo: HassioHostInfo;
|
||||
|
||||
@property() private _hassioInfo?: HassioInfo;
|
||||
|
||||
@property() private _hassOsInfo?: HassioHassOSInfo;
|
||||
|
||||
@property() private _hassInfo: HassioHomeAssistantInfo;
|
||||
@ -147,6 +151,7 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
||||
hass: this.hass,
|
||||
narrow: this.narrow,
|
||||
supervisorInfo: this._supervisorInfo,
|
||||
hassioInfo: this._hassioInfo,
|
||||
hostInfo: this._hostInfo,
|
||||
hassInfo: this._hassInfo,
|
||||
hassOsInfo: this._hassOsInfo,
|
||||
@ -156,6 +161,7 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
||||
el.hass = this.hass;
|
||||
el.narrow = this.narrow;
|
||||
el.supervisorInfo = this._supervisorInfo;
|
||||
el.hassioInfo = this._hassioInfo;
|
||||
el.hostInfo = this._hostInfo;
|
||||
el.hassInfo = this._hassInfo;
|
||||
el.hassOsInfo = this._hassOsInfo;
|
||||
@ -169,12 +175,14 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [supervisorInfo, hostInfo, hassInfo] = await Promise.all([
|
||||
const [supervisorInfo, hostInfo, hassInfo, hassioInfo] = await Promise.all([
|
||||
fetchHassioSupervisorInfo(this.hass),
|
||||
fetchHassioHostInfo(this.hass),
|
||||
fetchHassioHomeAssistantInfo(this.hass),
|
||||
fetchHassioInfo(this.hass),
|
||||
]);
|
||||
this._supervisorInfo = supervisorInfo;
|
||||
this._hassioInfo = hassioInfo;
|
||||
this._hostInfo = hostInfo;
|
||||
this._hassInfo = hassInfo;
|
||||
|
||||
|
@ -3,6 +3,7 @@ import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host";
|
||||
import {
|
||||
HassioHomeAssistantInfo,
|
||||
HassioSupervisorInfo,
|
||||
HassioInfo,
|
||||
} from "../../src/data/hassio/supervisor";
|
||||
import {
|
||||
HassRouterPage,
|
||||
@ -26,6 +27,8 @@ class HassioPanelRouter extends HassRouterPage {
|
||||
|
||||
@property({ attribute: false }) public supervisorInfo: HassioSupervisorInfo;
|
||||
|
||||
@property({ attribute: false }) public hassioInfo!: HassioInfo;
|
||||
|
||||
@property({ attribute: false }) public hostInfo: HassioHostInfo;
|
||||
|
||||
@property({ attribute: false }) public hassInfo: HassioHomeAssistantInfo;
|
||||
@ -54,6 +57,7 @@ class HassioPanelRouter extends HassRouterPage {
|
||||
el.route = this.route;
|
||||
el.narrow = this.narrow;
|
||||
el.supervisorInfo = this.supervisorInfo;
|
||||
el.hassioInfo = this.hassioInfo;
|
||||
el.hostInfo = this.hostInfo;
|
||||
el.hassInfo = this.hassInfo;
|
||||
el.hassOsInfo = this.hassOsInfo;
|
||||
|
@ -10,6 +10,7 @@ import { HassioHassOSInfo, HassioHostInfo } from "../../src/data/hassio/host";
|
||||
import {
|
||||
HassioHomeAssistantInfo,
|
||||
HassioSupervisorInfo,
|
||||
HassioInfo,
|
||||
} from "../../src/data/hassio/supervisor";
|
||||
import type { PageNavigation } from "../../src/layouts/hass-tabs-subpage";
|
||||
import { HomeAssistant, Route } from "../../src/types";
|
||||
@ -48,6 +49,8 @@ class HassioPanel extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public supervisorInfo!: HassioSupervisorInfo;
|
||||
|
||||
@property({ attribute: false }) public hassioInfo!: HassioInfo;
|
||||
|
||||
@property({ attribute: false }) public hostInfo!: HassioHostInfo;
|
||||
|
||||
@property({ attribute: false }) public hassInfo!: HassioHomeAssistantInfo;
|
||||
@ -61,6 +64,7 @@ class HassioPanel extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
.supervisorInfo=${this.supervisorInfo}
|
||||
.hassioInfo=${this.hassioInfo}
|
||||
.hostInfo=${this.hostInfo}
|
||||
.hassInfo=${this.hassInfo}
|
||||
.hassOsInfo=${this.hassOsInfo}
|
||||
|
@ -19,6 +19,7 @@ import {
|
||||
shutdownHost,
|
||||
updateOS,
|
||||
} from "../../../src/data/hassio/host";
|
||||
import { HassioInfo } from "../../../src/data/hassio/supervisor";
|
||||
import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
@ -35,6 +36,8 @@ class HassioHostInfo extends LitElement {
|
||||
|
||||
@property() public hostInfo!: HassioHostInfoType;
|
||||
|
||||
@property({ attribute: false }) public hassioInfo!: HassioInfo;
|
||||
|
||||
@property() public hassOsInfo!: HassioHassOSInfo;
|
||||
|
||||
@property() private _errors?: string;
|
||||
@ -54,6 +57,12 @@ class HassioHostInfo extends LitElement {
|
||||
<td>System</td>
|
||||
<td>${this.hostInfo.operating_system}</td>
|
||||
</tr>
|
||||
${!this.hostInfo.features.includes("hassos")
|
||||
? html`<tr>
|
||||
<td>Docker version</td>
|
||||
<td>${this.hassioInfo.docker}</td>
|
||||
</tr>`
|
||||
: ""}
|
||||
${this.hostInfo.deployment
|
||||
? html`
|
||||
<tr>
|
||||
|
@ -11,7 +11,10 @@ import {
|
||||
HassioHassOSInfo,
|
||||
HassioHostInfo,
|
||||
} from "../../../src/data/hassio/host";
|
||||
import { HassioSupervisorInfo } from "../../../src/data/hassio/supervisor";
|
||||
import {
|
||||
HassioSupervisorInfo,
|
||||
HassioInfo,
|
||||
} from "../../../src/data/hassio/supervisor";
|
||||
import "../../../src/layouts/hass-tabs-subpage";
|
||||
import { haStyle } from "../../../src/resources/styles";
|
||||
import { HomeAssistant, Route } from "../../../src/types";
|
||||
@ -31,9 +34,11 @@ class HassioSystem extends LitElement {
|
||||
|
||||
@property() public supervisorInfo!: HassioSupervisorInfo;
|
||||
|
||||
@property({ attribute: false }) public hassioInfo!: HassioInfo;
|
||||
|
||||
@property() public hostInfo!: HassioHostInfo;
|
||||
|
||||
@property() public hassOsInfo!: HassioHassOSInfo;
|
||||
@property({ attribute: false }) public hassOsInfo!: HassioHassOSInfo;
|
||||
|
||||
public render(): TemplateResult | void {
|
||||
return html`
|
||||
@ -55,6 +60,7 @@ class HassioSystem extends LitElement {
|
||||
></hassio-supervisor-info>
|
||||
<hassio-host-info
|
||||
.hass=${this.hass}
|
||||
.hassioInfo=${this.hassioInfo}
|
||||
.hostInfo=${this.hostInfo}
|
||||
.hassOsInfo=${this.hassOsInfo}
|
||||
></hassio-host-info>
|
||||
|
@ -74,6 +74,7 @@
|
||||
"@thomasloven/round-slider": "0.5.0",
|
||||
"@vaadin/vaadin-combo-box": "^5.0.10",
|
||||
"@vaadin/vaadin-date-picker": "^4.0.7",
|
||||
"@vue/web-component-wrapper": "^1.2.0",
|
||||
"@webcomponents/webcomponentsjs": "^2.2.7",
|
||||
"chart.js": "~2.8.0",
|
||||
"chartjs-chart-timeline": "^0.3.0",
|
||||
@ -106,6 +107,8 @@
|
||||
"roboto-fontface": "^0.10.0",
|
||||
"superstruct": "^0.6.1",
|
||||
"unfetch": "^4.1.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue2-daterange-picker": "^0.5.1",
|
||||
"web-animations-js": "^2.3.2",
|
||||
"workbox-core": "^5.1.3",
|
||||
"workbox-precaching": "^5.1.3",
|
||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name="home-assistant-frontend",
|
||||
version="20200613.0",
|
||||
version="20200620.0",
|
||||
description="The Home Assistant frontend",
|
||||
url="https://github.com/home-assistant/home-assistant-polymer",
|
||||
author="The Home Assistant Authors",
|
||||
|
@ -6,19 +6,18 @@ import {
|
||||
property,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { AuthProvider, fetchAuthProviders } from "../data/auth";
|
||||
import {
|
||||
AuthProvider,
|
||||
fetchAuthProviders,
|
||||
AuthUrlSearchParams,
|
||||
} from "../data/auth";
|
||||
import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin";
|
||||
import { registerServiceWorker } from "../util/register-service-worker";
|
||||
import "./ha-auth-flow";
|
||||
import { extractSearchParamsObject } from "../common/url/search-params";
|
||||
|
||||
import(/* webpackChunkName: "pick-auth-provider" */ "./ha-pick-auth-provider");
|
||||
|
||||
interface QueryParams {
|
||||
client_id?: string;
|
||||
redirect_uri?: string;
|
||||
state?: string;
|
||||
}
|
||||
|
||||
class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||
@property() public clientId?: string;
|
||||
|
||||
@ -33,14 +32,7 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||
constructor() {
|
||||
super();
|
||||
this.translationFragment = "page-authorize";
|
||||
const query: QueryParams = {};
|
||||
const values = location.search.substr(1).split("&");
|
||||
for (const item of values) {
|
||||
const value = item.split("=");
|
||||
if (value.length > 1) {
|
||||
query[decodeURIComponent(value[0])] = decodeURIComponent(value[1]);
|
||||
}
|
||||
}
|
||||
const query = extractSearchParamsObject() as AuthUrlSearchParams;
|
||||
if (query.client_id) {
|
||||
this.clientId = query.client_id;
|
||||
}
|
||||
@ -145,7 +137,7 @@ class HaAuthorize extends litLocalizeLiteMixin(LitElement) {
|
||||
response.status === 400 &&
|
||||
authProviders.code === "onboarding_required"
|
||||
) {
|
||||
location.href = "/?";
|
||||
location.href = `/onboarding.html${location.search}`;
|
||||
return;
|
||||
}
|
||||
|
||||
|
8
src/common/url/search-params.ts
Normal file
8
src/common/url/search-params.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export const extractSearchParamsObject = (): { [key: string]: string } => {
|
||||
const query = {};
|
||||
const searchParams = new URLSearchParams(location.search);
|
||||
for (const [key, value] of searchParams.entries()) {
|
||||
query[key] = value;
|
||||
}
|
||||
return query;
|
||||
};
|
@ -8,6 +8,9 @@ class HaProgressButton extends PolymerElement {
|
||||
static get template() {
|
||||
return html`
|
||||
<style>
|
||||
:host {
|
||||
outline: none;
|
||||
}
|
||||
.container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
228
src/components/date-range-picker.ts
Normal file
228
src/components/date-range-picker.ts
Normal file
@ -0,0 +1,228 @@
|
||||
import Vue from "vue";
|
||||
import wrap from "@vue/web-component-wrapper";
|
||||
import DateRangePicker from "vue2-daterange-picker";
|
||||
// @ts-ignore
|
||||
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { Constructor } from "../types";
|
||||
import { customElement } from "lit-element/lib/decorators";
|
||||
|
||||
const Component = Vue.extend({
|
||||
props: {
|
||||
twentyfourHours: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
ranges: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
startDate: {
|
||||
type: [String, Date],
|
||||
default() {
|
||||
return new Date();
|
||||
},
|
||||
},
|
||||
endDate: {
|
||||
type: [String, Date],
|
||||
default() {
|
||||
return new Date();
|
||||
},
|
||||
},
|
||||
},
|
||||
render(createElement) {
|
||||
// @ts-ignore
|
||||
return createElement(DateRangePicker, {
|
||||
props: {
|
||||
"time-picker": true,
|
||||
"auto-apply": false,
|
||||
opens: "right",
|
||||
"show-dropdowns": false,
|
||||
"time-picker24-hour": this.twentyfourHours,
|
||||
disabled: this.disabled,
|
||||
ranges: this.ranges ? {} : false,
|
||||
},
|
||||
model: {
|
||||
value: {
|
||||
startDate: this.startDate,
|
||||
endDate: this.endDate,
|
||||
},
|
||||
callback: (value) => {
|
||||
// @ts-ignore
|
||||
fireEvent(this.$el as HTMLElement, "change", value);
|
||||
},
|
||||
expression: "dateRange",
|
||||
},
|
||||
scopedSlots: {
|
||||
input() {
|
||||
return createElement("slot", {
|
||||
domProps: { name: "input" },
|
||||
});
|
||||
},
|
||||
header() {
|
||||
return createElement("slot", {
|
||||
domProps: { name: "header" },
|
||||
});
|
||||
},
|
||||
ranges() {
|
||||
return createElement("slot", {
|
||||
domProps: { name: "ranges" },
|
||||
});
|
||||
},
|
||||
footer() {
|
||||
return createElement("slot", {
|
||||
domProps: { name: "footer" },
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const WrappedElement: Constructor<HTMLElement> = wrap(Vue, Component);
|
||||
|
||||
@customElement("date-range-picker")
|
||||
class DateRangePickerElement extends WrappedElement {
|
||||
constructor() {
|
||||
super();
|
||||
const style = document.createElement("style");
|
||||
style.innerHTML = `
|
||||
${dateRangePickerStyles}
|
||||
.calendars {
|
||||
display: flex;
|
||||
}
|
||||
.daterangepicker {
|
||||
left: 0px !important;
|
||||
top: auto;
|
||||
background-color: var(--card-background-color);
|
||||
border: none;
|
||||
border-radius: var(--ha-card-border-radius, 4px);
|
||||
box-shadow: var(
|
||||
--ha-card-box-shadow,
|
||||
0px 2px 1px -1px rgba(0, 0, 0, 0.2),
|
||||
0px 1px 1px 0px rgba(0, 0, 0, 0.14),
|
||||
0px 1px 3px 0px rgba(0, 0, 0, 0.12)
|
||||
);
|
||||
color: var(--primary-text-color);
|
||||
min-width: initial !important;
|
||||
}
|
||||
.daterangepicker:after {
|
||||
border-bottom: 6px solid var(--card-background-color);
|
||||
}
|
||||
.daterangepicker .calendar-table {
|
||||
background-color: var(--card-background-color);
|
||||
border: none;
|
||||
}
|
||||
.daterangepicker .calendar-table td,
|
||||
.daterangepicker .calendar-table th {
|
||||
background-color: transparent;
|
||||
color: var(--secondary-text-color);
|
||||
border-radius: 0;
|
||||
outline: none;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.daterangepicker td.off,
|
||||
.daterangepicker td.off.end-date,
|
||||
.daterangepicker td.off.in-range,
|
||||
.daterangepicker td.off.start-date {
|
||||
background-color: var(--secondary-background-color);
|
||||
color: var(--disabled-text-color);
|
||||
}
|
||||
.daterangepicker td.in-range {
|
||||
background-color: var(--light-primary-color);
|
||||
color: var(--primary-text-color);
|
||||
}
|
||||
.daterangepicker td.active,
|
||||
.daterangepicker td.active:hover {
|
||||
background-color: var(--primary-color);
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
.daterangepicker td.start-date.end-date {
|
||||
border-radius: 50%;
|
||||
}
|
||||
.daterangepicker td.start-date {
|
||||
border-radius: 50% 0 0 50%;
|
||||
}
|
||||
.daterangepicker td.end-date {
|
||||
border-radius: 0 50% 50% 0;
|
||||
}
|
||||
.reportrange-text {
|
||||
background: none !important;
|
||||
padding: 0 !important;
|
||||
border: none !important;
|
||||
}
|
||||
.daterangepicker .calendar-table .next span,
|
||||
.daterangepicker .calendar-table .prev span {
|
||||
border: solid var(--primary-text-color);
|
||||
border-width: 0 2px 2px 0;
|
||||
}
|
||||
.daterangepicker .ranges li {
|
||||
outline: none;
|
||||
}
|
||||
.daterangepicker .ranges li:hover {
|
||||
background-color: var(--secondary-background-color);
|
||||
}
|
||||
.daterangepicker .ranges li.active {
|
||||
background-color: var(--primary-color);
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
.daterangepicker select.ampmselect,
|
||||
.daterangepicker select.hourselect,
|
||||
.daterangepicker select.minuteselect,
|
||||
.daterangepicker select.secondselect {
|
||||
background: transparent;
|
||||
border: 1px solid var(--divider-color);
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.daterangepicker .drp-buttons .btn {
|
||||
border: 1px solid var(--primary-color);
|
||||
background-color: transparent;
|
||||
color: var(--primary-color);
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.calendars-container {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.drp-calendar.col.right .calendar-table {
|
||||
display: none;
|
||||
}
|
||||
.daterangepicker.show-ranges .drp-calendar.left {
|
||||
border-left: 0px;
|
||||
}
|
||||
.daterangepicker .drp-calendar.left {
|
||||
padding: 8px;
|
||||
}
|
||||
.daterangepicker.show-calendar .ranges {
|
||||
margin-top: 0;
|
||||
padding-top: 8px;
|
||||
border-right: 1px solid var(--divider-color);
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
.calendars {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
.calendar-table {
|
||||
padding: 0 !important;
|
||||
}
|
||||
`;
|
||||
const shadowRoot = this.shadowRoot!;
|
||||
shadowRoot.appendChild(style);
|
||||
// Stop click events from reaching the document, otherwise it will close the picker immediately.
|
||||
shadowRoot.addEventListener("click", (ev) => ev.stopPropagation());
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"date-range-picker": DateRangePickerElement;
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ class HaCard extends LitElement {
|
||||
}
|
||||
|
||||
:host([outlined]) {
|
||||
box-shadow: 0 0 0 0;
|
||||
box-shadow: none;
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: var(
|
||||
|
195
src/components/ha-date-range-picker.ts
Normal file
195
src/components/ha-date-range-picker.ts
Normal file
@ -0,0 +1,195 @@
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { mdiCalendar } from "@mdi/js";
|
||||
import { formatDateTime } from "../common/datetime/format_date_time";
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import "./ha-svg-icon";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import "./date-range-picker";
|
||||
|
||||
export interface DateRangePickerRanges {
|
||||
[key: string]: [Date, Date];
|
||||
}
|
||||
|
||||
@customElement("ha-date-range-picker")
|
||||
export class HaDateRangePicker extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property() public startDate!: Date;
|
||||
|
||||
@property() public endDate!: Date;
|
||||
|
||||
@property() public ranges?: DateRangePickerRanges;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@property({ type: Boolean }) private _hour24format = false;
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
if (changedProps.has("hass")) {
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
if (!oldHass || oldHass.language !== this.hass.language) {
|
||||
this._hour24format = this._compute24hourFormat();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<date-range-picker
|
||||
?disabled=${this.disabled}
|
||||
twentyfour-hours=${this._hour24format}
|
||||
start-date=${this.startDate}
|
||||
end-date=${this.endDate}
|
||||
?ranges=${this.ranges !== undefined}
|
||||
>
|
||||
<div slot="input" class="date-range-inputs">
|
||||
<ha-svg-icon path=${mdiCalendar}></ha-svg-icon>
|
||||
<paper-input
|
||||
.value=${formatDateTime(this.startDate, this.hass.language)}
|
||||
.label=${this.hass.localize(
|
||||
"ui.components.date-range-picker.start_date"
|
||||
)}
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._handleInputClick}
|
||||
readonly
|
||||
></paper-input>
|
||||
<paper-input
|
||||
.value=${formatDateTime(this.endDate, this.hass.language)}
|
||||
label=${this.hass.localize(
|
||||
"ui.components.date-range-picker.end_date"
|
||||
)}
|
||||
.disabled=${this.disabled}
|
||||
@click=${this._handleInputClick}
|
||||
readonly
|
||||
></paper-input>
|
||||
</div>
|
||||
${this.ranges
|
||||
? html`<div slot="ranges" class="date-range-ranges">
|
||||
<mwc-list @click=${this._setDateRange}>
|
||||
${Object.entries(this.ranges).map(
|
||||
([name, dates]) => html`<mwc-list-item
|
||||
.activated=${this.startDate.getTime() ===
|
||||
dates[0].getTime() &&
|
||||
this.endDate.getTime() === dates[1].getTime()}
|
||||
.startDate=${dates[0]}
|
||||
.endDate=${dates[1]}
|
||||
>
|
||||
${name}
|
||||
</mwc-list-item>`
|
||||
)}
|
||||
</mwc-list>
|
||||
</div>`
|
||||
: ""}
|
||||
<div slot="footer" class="date-range-footer">
|
||||
<mwc-button @click=${this._cancelDateRange}
|
||||
>${this.hass.localize("ui.common.cancel")}</mwc-button
|
||||
>
|
||||
<mwc-button @click=${this._applyDateRange}
|
||||
>${this.hass.localize(
|
||||
"ui.components.date-range-picker.select"
|
||||
)}</mwc-button
|
||||
>
|
||||
</div>
|
||||
</date-range-picker>
|
||||
`;
|
||||
}
|
||||
|
||||
private _compute24hourFormat() {
|
||||
return (
|
||||
new Intl.DateTimeFormat(this.hass.language, {
|
||||
hour: "numeric",
|
||||
})
|
||||
.formatToParts(new Date(2020, 0, 1, 13))
|
||||
.find((part) => part.type === "hour")!.value.length === 2
|
||||
);
|
||||
}
|
||||
|
||||
private _setDateRange(ev: Event) {
|
||||
const target = ev.target as any;
|
||||
const startDate = target.startDate;
|
||||
const endDate = target.endDate;
|
||||
const dateRangePicker = this._dateRangePicker;
|
||||
dateRangePicker.clickRange([startDate, endDate]);
|
||||
dateRangePicker.clickedApply();
|
||||
}
|
||||
|
||||
private _cancelDateRange() {
|
||||
this._dateRangePicker.clickCancel();
|
||||
}
|
||||
|
||||
private _applyDateRange() {
|
||||
this._dateRangePicker.clickedApply();
|
||||
}
|
||||
|
||||
private get _dateRangePicker() {
|
||||
const dateRangePicker = this.shadowRoot!.querySelector(
|
||||
"date-range-picker"
|
||||
) as any;
|
||||
return dateRangePicker.vueComponent.$children[0];
|
||||
}
|
||||
|
||||
private _handleInputClick() {
|
||||
// close the date picker, so it will open again on the click event
|
||||
if (this._dateRangePicker.open) {
|
||||
this._dateRangePicker.open = false;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
ha-svg-icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.date-range-inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.date-range-ranges {
|
||||
border-right: 1px solid var(--divider-color);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
.date-range-ranges {
|
||||
border-right: none;
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
}
|
||||
|
||||
.date-range-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 8px;
|
||||
border-top: 1px solid var(--divider-color);
|
||||
}
|
||||
|
||||
paper-input {
|
||||
display: inline-block;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
paper-input:last-child {
|
||||
margin-left: 8px;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-date-range-picker": HaDateRangePicker;
|
||||
}
|
||||
}
|
@ -54,7 +54,7 @@ class HaMarkdown extends LitElement {
|
||||
}
|
||||
ha-markdown-element code,
|
||||
pre {
|
||||
background-color: var(--markdown-code-background-color, #f6f8fa);
|
||||
background-color: var(--markdown-code-background-color, none);
|
||||
border-radius: 3px;
|
||||
}
|
||||
ha-markdown-element code {
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
export interface AuthUrlSearchParams {
|
||||
client_id?: string;
|
||||
redirect_uri?: string;
|
||||
state?: string;
|
||||
}
|
||||
|
||||
export interface AuthProvider {
|
||||
name: string;
|
||||
id: string;
|
||||
|
@ -5,7 +5,7 @@ import { HomeAssistant } from "../types";
|
||||
import { DataEntryFlowProgress, DataEntryFlowStep } from "./data_entry_flow";
|
||||
import { domainToName } from "./integration";
|
||||
|
||||
export const DISCOVERY_SOURCES = ["unignore", "homekit", "ssdp", "zeroconf"];
|
||||
export const DISCOVERY_SOURCES = ["unignore", "homekit", "ssdp", "zeroconf", "discovery"];
|
||||
|
||||
export const createConfigFlow = (hass: HomeAssistant, handler: string) =>
|
||||
hass.callApi<DataEntryFlowStep>("POST", "config/config_entries/flow", {
|
||||
|
@ -4,6 +4,20 @@ import { hassioApiResultExtractor, HassioResponse } from "./common";
|
||||
export type HassioHomeAssistantInfo = any;
|
||||
export type HassioSupervisorInfo = any;
|
||||
|
||||
export type HassioInfo = {
|
||||
arch: string;
|
||||
channel: string;
|
||||
docker: string;
|
||||
hassos?: string;
|
||||
homeassistant: string;
|
||||
hostname: string;
|
||||
logging: string;
|
||||
maching: string;
|
||||
supervisor: string;
|
||||
supported_arch: string[];
|
||||
timezone: string;
|
||||
};
|
||||
|
||||
export type HassioPanelInfo = PanelInfo<
|
||||
| undefined
|
||||
| {
|
||||
@ -38,6 +52,12 @@ export const fetchHassioSupervisorInfo = async (hass: HomeAssistant) => {
|
||||
);
|
||||
};
|
||||
|
||||
export const fetchHassioInfo = async (hass: HomeAssistant) => {
|
||||
return hassioApiResultExtractor(
|
||||
await hass.callApi<HassioResponse<HassioInfo>>("GET", "hassio/info")
|
||||
);
|
||||
};
|
||||
|
||||
export const fetchHassioLogs = async (
|
||||
hass: HomeAssistant,
|
||||
provider: string
|
||||
|
@ -1,7 +1,67 @@
|
||||
import { HomeAssistant } from "../types";
|
||||
|
||||
export interface LogbookEntry {
|
||||
when: string;
|
||||
name: string;
|
||||
message: string;
|
||||
entity_id?: string;
|
||||
domain: string;
|
||||
context_user_id?: string;
|
||||
}
|
||||
|
||||
const DATA_CACHE: {
|
||||
[cacheKey: string]: { [entityId: string]: Promise<LogbookEntry[]> };
|
||||
} = {};
|
||||
|
||||
export const getLogbookData = (
|
||||
hass: HomeAssistant,
|
||||
startDate: string,
|
||||
endDate: string,
|
||||
entityId?: string
|
||||
) => {
|
||||
const ALL_ENTITIES = "*";
|
||||
|
||||
if (!entityId) {
|
||||
entityId = ALL_ENTITIES;
|
||||
}
|
||||
|
||||
const cacheKey = `${startDate}${endDate}`;
|
||||
|
||||
if (!DATA_CACHE[cacheKey]) {
|
||||
DATA_CACHE[cacheKey] = {};
|
||||
}
|
||||
|
||||
if (DATA_CACHE[cacheKey][entityId]) {
|
||||
return DATA_CACHE[cacheKey][entityId];
|
||||
}
|
||||
|
||||
if (entityId !== ALL_ENTITIES && DATA_CACHE[cacheKey][ALL_ENTITIES]) {
|
||||
return DATA_CACHE[cacheKey][ALL_ENTITIES].then((entities) =>
|
||||
entities.filter((entity) => entity.entity_id === entityId)
|
||||
);
|
||||
}
|
||||
|
||||
DATA_CACHE[cacheKey][entityId] = getLogbookDataFromServer(
|
||||
hass,
|
||||
startDate,
|
||||
endDate,
|
||||
entityId !== ALL_ENTITIES ? entityId : undefined
|
||||
).then((entries) => entries.reverse());
|
||||
return DATA_CACHE[cacheKey][entityId];
|
||||
};
|
||||
|
||||
const getLogbookDataFromServer = async (
|
||||
hass: HomeAssistant,
|
||||
startDate: string,
|
||||
endDate: string,
|
||||
entityId?: string
|
||||
) => {
|
||||
const url = `logbook/${startDate}?end_time=${endDate}${
|
||||
entityId ? `&entity=${entityId}` : ""
|
||||
}`;
|
||||
return hass.callApi<LogbookEntry[]>("GET", url);
|
||||
};
|
||||
|
||||
export const clearLogbookCache = (startDate, endDate) => {
|
||||
DATA_CACHE[`${startDate}${endDate}`] = {};
|
||||
};
|
||||
|
@ -51,7 +51,7 @@ export const onboardCoreConfigStep = (hass: HomeAssistant) =>
|
||||
|
||||
export const onboardIntegrationStep = (
|
||||
hass: HomeAssistant,
|
||||
params: { client_id: string }
|
||||
params: { client_id: string; redirect_uri: string }
|
||||
) =>
|
||||
hass.callApi<OnboardingIntegrationStepResponse>(
|
||||
"POST",
|
||||
|
@ -42,6 +42,8 @@ class StepFlowPickHandler extends LitElement {
|
||||
|
||||
private _width?: number;
|
||||
|
||||
private _height?: number;
|
||||
|
||||
private _getHandlers = memoizeOne(
|
||||
(h: string[], filter?: string, _localize?: LocalizeFunc) => {
|
||||
const handlers: HandlerObj[] = h.map((handler) => {
|
||||
@ -82,7 +84,10 @@ class StepFlowPickHandler extends LitElement {
|
||||
@value-changed=${this._filterChanged}
|
||||
></search-input>
|
||||
<div
|
||||
style=${styleMap({ width: `${this._width}px` })}
|
||||
style=${styleMap({
|
||||
width: `${this._width}px`,
|
||||
height: `${this._height}px`,
|
||||
})}
|
||||
class=${classMap({ advanced: Boolean(this.showAdvanced) })}
|
||||
>
|
||||
${handlers.map(
|
||||
@ -139,13 +144,20 @@ class StepFlowPickHandler extends LitElement {
|
||||
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
// Store the width so that when we search, box doesn't jump
|
||||
// Store the width and height so that when we search, box doesn't jump
|
||||
const div = this.shadowRoot!.querySelector("div")!;
|
||||
if (!this._width) {
|
||||
const width = this.shadowRoot!.querySelector("div")!.clientWidth;
|
||||
const width = div.clientWidth;
|
||||
if (width) {
|
||||
this._width = width;
|
||||
}
|
||||
}
|
||||
if (!this._height) {
|
||||
const height = div.clientHeight;
|
||||
if (height) {
|
||||
this._height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _filterChanged(e) {
|
||||
@ -166,8 +178,8 @@ class StepFlowPickHandler extends LitElement {
|
||||
configFlowContentStyles,
|
||||
css`
|
||||
img {
|
||||
max-width: 40px;
|
||||
max-height: 40px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
search-input {
|
||||
display: block;
|
||||
@ -180,12 +192,12 @@ class StepFlowPickHandler extends LitElement {
|
||||
overflow: auto;
|
||||
max-height: 600px;
|
||||
}
|
||||
@media all and (max-height: 1px) {
|
||||
@media all and (max-height: 900px) {
|
||||
div {
|
||||
max-height: calc(100vh - 205px);
|
||||
max-height: calc(100vh - 134px);
|
||||
}
|
||||
div.advanced {
|
||||
max-height: calc(100vh - 300px);
|
||||
max-height: calc(100vh - 250px);
|
||||
}
|
||||
}
|
||||
paper-icon-item {
|
||||
|
@ -66,7 +66,7 @@ class DialogDeviceRegistryDetail extends LitElement {
|
||||
<paper-input
|
||||
.value=${this._nameByUser}
|
||||
@value-changed=${this._nameChanged}
|
||||
.label=${this.hass.localize("ui.dialogs.devices.name")}
|
||||
.label=${this.hass.localize("ui.panel.config.devices.name")}
|
||||
.placeholder=${device.name || ""}
|
||||
.disabled=${this._submitting}
|
||||
></paper-input>
|
||||
|
@ -86,7 +86,7 @@ class MoreInfoControls extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
<div class="main-title" main-title="" on-click="enlarge">
|
||||
[[_computeStateName(stateObj)]]
|
||||
</div>
|
||||
<template is="dom-if" if="[[_computeConfig(hass)]]">
|
||||
<template is="dom-if" if="[[hass.user.is_admin]]">
|
||||
<ha-icon-button
|
||||
aria-label$="[[localize('ui.dialogs.more_info_control.settings')]]"
|
||||
icon="hass:settings"
|
||||
@ -219,10 +219,6 @@ class MoreInfoControls extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
return stateObj ? computeStateName(stateObj) : "";
|
||||
}
|
||||
|
||||
_computeConfig(hass) {
|
||||
return hass.user.is_admin && isComponentLoaded(hass, "config");
|
||||
}
|
||||
|
||||
_computeEdit(hass, stateObj) {
|
||||
const domain = this._computeDomain(stateObj);
|
||||
return (
|
||||
|
@ -2,7 +2,7 @@
|
||||
if (navigator.userAgent.indexOf("Android") === -1 &&
|
||||
navigator.userAgent.indexOf("CrOS") === -1) {
|
||||
function _pf(src, type) {
|
||||
const el = document.createElement("link");
|
||||
var el = document.createElement("link");
|
||||
el.rel = "preload";
|
||||
el.as = "font";
|
||||
el.type = "font/woff2";
|
||||
|
@ -58,12 +58,13 @@
|
||||
window.customPanelJS = "<%= latestCustomPanelJS %>";
|
||||
window.latestJS = true;
|
||||
</script>
|
||||
<script>
|
||||
{% for extra_module in extra_modules -%}
|
||||
<script type="module" crossorigin="use-credentials" src="{{ extra_module }}"></script>
|
||||
import("{{ extra_module }}");
|
||||
{% endfor -%}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
if (!window.latestJS) {
|
||||
window.customPanelJS = "<%= es5CustomPanelJS %>";
|
||||
|
||||
@ -79,11 +80,14 @@
|
||||
_ls("<%= es5CoreJS %>");
|
||||
_ls("<%= es5AppJS %>");
|
||||
<% } %>
|
||||
{% for extra_script in extra_js_es5 -%}
|
||||
_ls("{{ extra_script }}");
|
||||
{% endfor -%}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
if (!window.latestJS) {
|
||||
{% for extra_script in extra_js_es5 -%}
|
||||
_ls("{{ extra_script }}");
|
||||
{% endfor -%}
|
||||
}
|
||||
</script>
|
||||
|
||||
{% for extra_url in extra_urls -%}
|
||||
|
@ -1,9 +1,9 @@
|
||||
import {
|
||||
Auth,
|
||||
createConnection,
|
||||
genClientId,
|
||||
getAuth,
|
||||
subscribeConfig,
|
||||
genClientId,
|
||||
} from "home-assistant-js-websocket";
|
||||
import {
|
||||
customElement,
|
||||
@ -14,12 +14,12 @@ import {
|
||||
} from "lit-element";
|
||||
import { HASSDomEvent } from "../common/dom/fire_event";
|
||||
import { subscribeOne } from "../common/util/subscribe-one";
|
||||
import { hassUrl } from "../data/auth";
|
||||
import { hassUrl, AuthUrlSearchParams } from "../data/auth";
|
||||
import {
|
||||
fetchOnboardingOverview,
|
||||
OnboardingResponses,
|
||||
OnboardingStep,
|
||||
ValidOnboardingStep,
|
||||
onboardIntegrationStep,
|
||||
} from "../data/onboarding";
|
||||
import { subscribeUser } from "../data/ws-user";
|
||||
import { litLocalizeLiteMixin } from "../mixins/lit-localize-lite-mixin";
|
||||
@ -28,19 +28,28 @@ import { HomeAssistant } from "../types";
|
||||
import { registerServiceWorker } from "../util/register-service-worker";
|
||||
import "./onboarding-create-user";
|
||||
import "./onboarding-loading";
|
||||
import { extractSearchParamsObject } from "../common/url/search-params";
|
||||
|
||||
interface OnboardingEvent<T extends ValidOnboardingStep> {
|
||||
type: T;
|
||||
result: OnboardingResponses[T];
|
||||
}
|
||||
type OnboardingEvent =
|
||||
| {
|
||||
type: "user";
|
||||
result: OnboardingResponses["user"];
|
||||
}
|
||||
| {
|
||||
type: "core_config";
|
||||
result: OnboardingResponses["core_config"];
|
||||
}
|
||||
| {
|
||||
type: "integration";
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"onboarding-step": OnboardingEvent<ValidOnboardingStep>;
|
||||
"onboarding-step": OnboardingEvent;
|
||||
}
|
||||
|
||||
interface GlobalEventHandlersEventMap {
|
||||
"onboarding-step": HASSDomEvent<OnboardingEvent<ValidOnboardingStep>>;
|
||||
"onboarding-step": HASSDomEvent<OnboardingEvent>;
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,9 +159,7 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private async _handleStepDone(
|
||||
ev: HASSDomEvent<OnboardingEvent<ValidOnboardingStep>>
|
||||
) {
|
||||
private async _handleStepDone(ev: HASSDomEvent<OnboardingEvent>) {
|
||||
const stepResult = ev.detail;
|
||||
this._steps = this._steps!.map((step) =>
|
||||
step.step === stepResult.type ? { ...step, done: true } : step
|
||||
@ -176,9 +183,41 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
||||
} else if (stepResult.type === "core_config") {
|
||||
// We do nothing
|
||||
} else if (stepResult.type === "integration") {
|
||||
const result = stepResult.result as OnboardingResponses["integration"];
|
||||
this._loading = true;
|
||||
|
||||
// Determine if oauth redirect has been provided
|
||||
const externalAuthParams = extractSearchParamsObject() as AuthUrlSearchParams;
|
||||
const authParams =
|
||||
externalAuthParams.client_id && externalAuthParams.redirect_uri
|
||||
? externalAuthParams
|
||||
: {
|
||||
client_id: genClientId(),
|
||||
redirect_uri: `${location.protocol}//${location.host}/?auth_callback=1`,
|
||||
state: btoa(
|
||||
JSON.stringify({
|
||||
hassUrl: `${location.protocol}//${location.host}`,
|
||||
clientId: genClientId(),
|
||||
})
|
||||
),
|
||||
};
|
||||
|
||||
let result: OnboardingResponses["integration"];
|
||||
|
||||
try {
|
||||
result = await onboardIntegrationStep(this.hass!, {
|
||||
client_id: authParams.client_id!,
|
||||
redirect_uri: authParams.redirect_uri!,
|
||||
});
|
||||
} catch (err) {
|
||||
this.hass!.connection.close();
|
||||
await this.hass!.auth.revoke();
|
||||
|
||||
alert(`Unable to finish onboarding: ${err.message}`);
|
||||
|
||||
document.location.assign("/?");
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't close the connection manually, the connection will be
|
||||
// closed when we navigate away from the page. Firefox allows JS to
|
||||
// continue to execute, and so HAWS will automatically reconnect once
|
||||
@ -191,17 +230,17 @@ class HaOnboarding extends litLocalizeLiteMixin(HassElement) {
|
||||
// Revoke current auth token.
|
||||
await this.hass!.auth.revoke();
|
||||
|
||||
const state = btoa(
|
||||
JSON.stringify({
|
||||
hassUrl: `${location.protocol}//${location.host}`,
|
||||
clientId: genClientId(),
|
||||
})
|
||||
);
|
||||
document.location.assign(
|
||||
`/?auth_callback=1&code=${encodeURIComponent(
|
||||
result.auth_code
|
||||
)}&state=${state}`
|
||||
);
|
||||
// Build up the url to redirect to
|
||||
let redirectUrl = authParams.redirect_uri!;
|
||||
redirectUrl +=
|
||||
(redirectUrl.includes("?") ? "&" : "?") +
|
||||
`code=${encodeURIComponent(result.auth_code)}`;
|
||||
|
||||
if (authParams.state) {
|
||||
redirectUrl += `&state=${encodeURIComponent(authParams.state)}`;
|
||||
}
|
||||
|
||||
document.location.assign(redirectUrl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import "@material/mwc-button/mwc-button";
|
||||
import { genClientId } from "home-assistant-js-websocket";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
@ -21,7 +20,6 @@ import {
|
||||
} from "../data/config_flow";
|
||||
import { DataEntryFlowProgress } from "../data/data_entry_flow";
|
||||
import { domainToName } from "../data/integration";
|
||||
import { onboardIntegrationStep } from "../data/onboarding";
|
||||
import {
|
||||
loadConfigFlowDialog,
|
||||
showConfigFlowDialog,
|
||||
@ -169,12 +167,8 @@ class OnboardingIntegrations extends LitElement {
|
||||
}
|
||||
|
||||
private async _finish() {
|
||||
const result = await onboardIntegrationStep(this.hass, {
|
||||
client_id: genClientId(),
|
||||
});
|
||||
fireEvent(this, "onboarding-step", {
|
||||
type: "integration",
|
||||
result,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -54,9 +54,7 @@ class HaConfigAutomation extends HassRouterPage {
|
||||
private _getAutomations = memoizeOne(
|
||||
(states: HassEntities): AutomationEntity[] => {
|
||||
return Object.values(states).filter(
|
||||
(entity) =>
|
||||
computeStateDomain(entity) === "automation" &&
|
||||
!entity.attributes.hidden
|
||||
(entity) => computeStateDomain(entity) === "automation"
|
||||
) as AutomationEntity[];
|
||||
}
|
||||
);
|
||||
|
@ -85,6 +85,36 @@ class HaConfigDashboard extends LitElement {
|
||||
</ha-card>
|
||||
`
|
||||
)}
|
||||
${isComponentLoaded(this.hass, "zha")
|
||||
? html`
|
||||
<div class="promo-advanced">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integration_panel_move.missing_zha",
|
||||
"integrations_page",
|
||||
html`<a href="/config/integrations">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integration_panel_move.link_integration_page"
|
||||
)}
|
||||
</a>`
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
${isComponentLoaded(this.hass, "zwave")
|
||||
? html`
|
||||
<div class="promo-advanced">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integration_panel_move.missing_zwave",
|
||||
"integrations_page",
|
||||
html`<a href="/config/integrations">
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.integration_panel_move.link_integration_page"
|
||||
)}
|
||||
</a>`
|
||||
)}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
${!this.showAdvanced
|
||||
? html`
|
||||
<div class="promo-advanced">
|
||||
|
@ -8,15 +8,18 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import "../../components/ha-dialog";
|
||||
import "../../components/ha-switch";
|
||||
import "../../components/ha-formfield";
|
||||
import type { HaSwitch } from "../../components/ha-switch";
|
||||
import { computeDeviceName } from "../../data/device_registry";
|
||||
import { fetchMQTTDebugInfo, MQTTDeviceDebugInfo } from "../../data/mqtt";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { computeStateName } from "../../../../../../common/entity/compute_state_name";
|
||||
import "../../../../../../components/ha-dialog";
|
||||
import "../../../../../../components/ha-switch";
|
||||
import "../../../../../../components/ha-formfield";
|
||||
import type { HaSwitch } from "../../../../../../components/ha-switch";
|
||||
import { computeDeviceName } from "../../../../../../data/device_registry";
|
||||
import {
|
||||
fetchMQTTDebugInfo,
|
||||
MQTTDeviceDebugInfo,
|
||||
} from "../../../../../../data/mqtt";
|
||||
import { haStyleDialog } from "../../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../../types";
|
||||
import "./mqtt-discovery-payload";
|
||||
import "./mqtt-messages";
|
||||
import { MQTTDeviceDebugInfoDialogParams } from "./show-dialog-mqtt-device-debug-info";
|
||||
@ -187,19 +190,19 @@ class DialogMQTTDeviceDebugInfo extends LitElement {
|
||||
<li class="triggerlistitem">
|
||||
MQTT discovery data:
|
||||
<ul class="discoverydata">
|
||||
<li>
|
||||
Topic:
|
||||
<code>${trigger.discovery_data.topic}</code>
|
||||
</li>
|
||||
<li>
|
||||
<mqtt-discovery-payload
|
||||
.hass=${this.hass}
|
||||
.payload=${trigger.discovery_data.payload}
|
||||
.showAsYaml=${this._showAsYaml}
|
||||
.summary=${"Payload"}
|
||||
>
|
||||
</li>
|
||||
</mqtt-discovery-payload>
|
||||
<li>
|
||||
Topic:
|
||||
<code>${trigger.discovery_data.topic}</code>
|
||||
</li>
|
||||
<li>
|
||||
<mqtt-discovery-payload
|
||||
.hass=${this.hass}
|
||||
.payload=${trigger.discovery_data.payload}
|
||||
.showAsYaml=${this._showAsYaml}
|
||||
.summary=${"Payload"}
|
||||
>
|
||||
</mqtt-discovery-payload>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
`
|
@ -7,12 +7,12 @@ import {
|
||||
TemplateResult,
|
||||
css,
|
||||
} from "lit-element";
|
||||
import { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import { removeMQTTDeviceEntry } from "../../../../../data/mqtt";
|
||||
import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||
import { showMQTTDeviceDebugInfoDialog } from "../../../../../dialogs/mqtt-device-debug-info-dialog/show-dialog-mqtt-device-debug-info";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||
import { removeMQTTDeviceEntry } from "../../../../../../data/mqtt";
|
||||
import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box";
|
||||
import { showMQTTDeviceDebugInfoDialog } from "./show-dialog-mqtt-device-debug-info";
|
||||
import { haStyle } from "../../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../../types";
|
||||
|
||||
@customElement("ha-device-actions-mqtt")
|
||||
export class HaDeviceActionsMqtt extends LitElement {
|
@ -9,9 +9,9 @@ import {
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { classMap } from "lit-html/directives/class-map";
|
||||
import { formatTimeWithSeconds } from "../../common/datetime/format_time";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { MQTTMessage } from "../../data/mqtt";
|
||||
import { formatTimeWithSeconds } from "../../../../../../common/datetime/format_time";
|
||||
import { HomeAssistant } from "../../../../../../types";
|
||||
import { MQTTMessage } from "../../../../../../data/mqtt";
|
||||
|
||||
@customElement("mqtt-messages")
|
||||
class MQTTMessages extends LitElement {
|
@ -1,5 +1,5 @@
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import { fireEvent } from "../../../../../../common/dom/fire_event";
|
||||
import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||
|
||||
export interface MQTTDeviceDebugInfoDialogParams {
|
||||
device: DeviceRegistryEntry;
|
@ -8,17 +8,18 @@ import {
|
||||
css,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||
import { haStyle } from "../../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../../types";
|
||||
import {
|
||||
ZHADevice,
|
||||
fetchZHADevice,
|
||||
reconfigureNode,
|
||||
} from "../../../../../data/zha";
|
||||
import { navigate } from "../../../../../common/navigate";
|
||||
import { showZHADeviceZigbeeInfoDialog } from "../../../../../dialogs/zha-device-zigbee-signature-dialog/show-dialog-zha-device-zigbee-info";
|
||||
import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||
} from "../../../../../../data/zha";
|
||||
import { navigate } from "../../../../../../common/navigate";
|
||||
import { showZHADeviceZigbeeInfoDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info";
|
||||
import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box";
|
||||
import { showZHAClusterDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-cluster";
|
||||
|
||||
@customElement("ha-device-actions-zha")
|
||||
export class HaDeviceActionsZha extends LitElement {
|
||||
@ -72,6 +73,11 @@ export class HaDeviceActionsZha extends LitElement {
|
||||
"ui.dialogs.zha_device_info.buttons.zigbee_information"
|
||||
)}
|
||||
</mwc-button>
|
||||
<mwc-button @click=${this._showClustersDialog}>
|
||||
${this.hass!.localize(
|
||||
"ui.dialogs.zha_device_info.buttons.clusters"
|
||||
)}
|
||||
</mwc-button>
|
||||
<mwc-button class="warning" @click=${this._removeDevice}>
|
||||
${this.hass!.localize(
|
||||
"ui.dialogs.zha_device_info.buttons.remove"
|
||||
@ -82,6 +88,10 @@ export class HaDeviceActionsZha extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private async _showClustersDialog(): Promise<void> {
|
||||
await showZHAClusterDialog(this, { device: this._zhaDevice! });
|
||||
}
|
||||
|
||||
private async _onReconfigureNodeClick(): Promise<void> {
|
||||
if (!this.hass) {
|
||||
return;
|
@ -8,11 +8,11 @@ import {
|
||||
css,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { ZHADevice, fetchZHADevice } from "../../../../../data/zha";
|
||||
import { formatAsPaddedHex } from "../../../integrations/integration-panels/zha/functions";
|
||||
import { DeviceRegistryEntry } from "../../../../../../data/device_registry";
|
||||
import { haStyle } from "../../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../../types";
|
||||
import { ZHADevice, fetchZHADevice } from "../../../../../../data/zha";
|
||||
import { formatAsPaddedHex } from "../../../../integrations/integration-panels/zha/functions";
|
||||
|
||||
@customElement("ha-device-info-zha")
|
||||
export class HaDeviceActionsZha extends LitElement {
|
@ -477,7 +477,9 @@ export class HaConfigDevicePage extends LitElement {
|
||||
): TemplateResult[] {
|
||||
const templates: TemplateResult[] = [];
|
||||
if (integrations.includes("mqtt")) {
|
||||
import("./device-detail/integration-elements/ha-device-actions-mqtt");
|
||||
import(
|
||||
"./device-detail/integration-elements/mqtt/ha-device-actions-mqtt"
|
||||
);
|
||||
templates.push(html`
|
||||
<div class="card-actions" slot="actions">
|
||||
<ha-device-actions-mqtt
|
||||
@ -488,8 +490,8 @@ export class HaConfigDevicePage extends LitElement {
|
||||
`);
|
||||
}
|
||||
if (integrations.includes("zha")) {
|
||||
import("./device-detail/integration-elements/ha-device-actions-zha");
|
||||
import("./device-detail/integration-elements/ha-device-info-zha");
|
||||
import("./device-detail/integration-elements/zha/ha-device-actions-zha");
|
||||
import("./device-detail/integration-elements/zha/ha-device-info-zha");
|
||||
templates.push(html`
|
||||
<ha-device-info-zha
|
||||
.hass=${this.hass}
|
||||
|
@ -323,6 +323,13 @@ class HaPanelConfig extends HassRouterPage {
|
||||
/* webpackChunkName: "panel-config-zwave" */ "./integrations/integration-panels/zwave/ha-config-zwave"
|
||||
),
|
||||
},
|
||||
mqtt: {
|
||||
tag: "mqtt-config-panel",
|
||||
load: () =>
|
||||
import(
|
||||
/* webpackChunkName: "panel-config-mqtt" */ "./integrations/integration-panels/mqtt/mqtt-config-panel"
|
||||
),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -46,6 +46,10 @@ declare global {
|
||||
}
|
||||
|
||||
const integrationsWithPanel = {
|
||||
mqtt: {
|
||||
buttonLocalizeKey: "ui.panel.config.mqtt.button",
|
||||
path: "/config/mqtt",
|
||||
},
|
||||
zha: {
|
||||
buttonLocalizeKey: "ui.panel.config.zha.button",
|
||||
path: "/config/zha/dashboard",
|
||||
|
@ -9,13 +9,14 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-code-editor";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import "../../../../../components/ha-card";
|
||||
import "../../../../../components/ha-code-editor";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import "./mqtt-subscribe-card";
|
||||
import "../../../../../layouts/hass-subpage";
|
||||
|
||||
@customElement("developer-tools-mqtt")
|
||||
@customElement("mqtt-config-panel")
|
||||
class HaPanelDevMqtt extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@ -37,43 +38,41 @@ class HaPanelDevMqtt extends LitElement {
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div class="content">
|
||||
<ha-card
|
||||
header="${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.description_publish"
|
||||
)}"
|
||||
>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
label="${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.topic"
|
||||
)}"
|
||||
.value=${this.topic}
|
||||
@value-changed=${this._handleTopic}
|
||||
></paper-input>
|
||||
<hass-subpage>
|
||||
<div class="content">
|
||||
<ha-card
|
||||
header="${this.hass.localize(
|
||||
"ui.panel.config.mqtt.description_publish"
|
||||
)}"
|
||||
>
|
||||
<div class="card-content">
|
||||
<paper-input
|
||||
label="${this.hass.localize("ui.panel.config.mqtt.topic")}"
|
||||
.value=${this.topic}
|
||||
@value-changed=${this._handleTopic}
|
||||
></paper-input>
|
||||
|
||||
<p>
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.payload"
|
||||
)}
|
||||
</p>
|
||||
<ha-code-editor
|
||||
mode="jinja2"
|
||||
.value="${this.payload}"
|
||||
@value-changed=${this._handlePayload}
|
||||
></ha-code-editor>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._publish}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.publish"
|
||||
)}</mwc-button
|
||||
>
|
||||
</div>
|
||||
</ha-card>
|
||||
<p>
|
||||
${this.hass.localize("ui.panel.config.mqtt.payload")}
|
||||
</p>
|
||||
<ha-code-editor
|
||||
mode="jinja2"
|
||||
.value="${this.payload}"
|
||||
@value-changed=${this._handlePayload}
|
||||
></ha-code-editor>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<mwc-button @click=${this._publish}
|
||||
>${this.hass.localize(
|
||||
"ui.panel.config.mqtt.publish"
|
||||
)}</mwc-button
|
||||
>
|
||||
</div>
|
||||
</ha-card>
|
||||
|
||||
<mqtt-subscribe-card .hass=${this.hass}></mqtt-subscribe-card>
|
||||
</div>
|
||||
<mqtt-subscribe-card .hass=${this.hass}></mqtt-subscribe-card>
|
||||
</div>
|
||||
</hass-subpage>
|
||||
`;
|
||||
}
|
||||
|
@ -9,10 +9,10 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { formatTime } from "../../../common/datetime/format_time";
|
||||
import "../../../components/ha-card";
|
||||
import { MQTTMessage, subscribeMQTTTopic } from "../../../data/mqtt";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { formatTime } from "../../../../../common/datetime/format_time";
|
||||
import "../../../../../components/ha-card";
|
||||
import { MQTTMessage, subscribeMQTTTopic } from "../../../../../data/mqtt";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
|
||||
@customElement("mqtt-subscribe-card")
|
||||
class MqttSubscribeCard extends LitElement {
|
||||
@ -43,18 +43,14 @@ class MqttSubscribeCard extends LitElement {
|
||||
return html`
|
||||
<ha-card
|
||||
header="${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.description_listen"
|
||||
"ui.panel.config.mqtt.description_listen"
|
||||
)}"
|
||||
>
|
||||
<form>
|
||||
<paper-input
|
||||
.label=${this._subscribed
|
||||
? this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.listening_to"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.subscribe_to"
|
||||
)}
|
||||
? this.hass.localize("ui.panel.config.mqtt.listening_to")
|
||||
: this.hass.localize("ui.panel.config.mqtt.subscribe_to")}
|
||||
.disabled=${this._subscribed !== undefined}
|
||||
.value=${this._topic}
|
||||
@value-changed=${this._valueChanged}
|
||||
@ -65,12 +61,8 @@ class MqttSubscribeCard extends LitElement {
|
||||
type="submit"
|
||||
>
|
||||
${this._subscribed
|
||||
? this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.stop_listening"
|
||||
)
|
||||
: this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.start_listening"
|
||||
)}
|
||||
? this.hass.localize("ui.panel.config.mqtt.stop_listening")
|
||||
: this.hass.localize("ui.panel.config.mqtt.start_listening")}
|
||||
</mwc-button>
|
||||
</form>
|
||||
<div class="events">
|
||||
@ -78,7 +70,7 @@ class MqttSubscribeCard extends LitElement {
|
||||
(msg) => html`
|
||||
<div class="event">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.message_received",
|
||||
"ui.panel.config.mqtt.message_received",
|
||||
"id",
|
||||
msg.id,
|
||||
"topic",
|
@ -0,0 +1,143 @@
|
||||
import {
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import "../../../../../components/ha-code-editor";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
import { haStyleDialog } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { ZHADeviceZigbeeInfoDialogParams } from "./show-dialog-zha-device-zigbee-info";
|
||||
import {
|
||||
ZHADevice,
|
||||
Cluster,
|
||||
ZHAGroup,
|
||||
fetchBindableDevices,
|
||||
fetchGroups,
|
||||
} from "../../../../../data/zha";
|
||||
import { ZHAClusterSelectedParams } from "./types";
|
||||
import "./zha-cluster-attributes";
|
||||
import "./zha-cluster-commands";
|
||||
import "./zha-clusters";
|
||||
import "./zha-device-binding";
|
||||
import "./zha-group-binding";
|
||||
import { HASSDomEvent } from "../../../../../common/dom/fire_event";
|
||||
import { sortZHADevices, sortZHAGroups } from "./functions";
|
||||
|
||||
@customElement("dialog-zha-cluster")
|
||||
class DialogZHACluster extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property() private _device?: ZHADevice;
|
||||
|
||||
@property() private _selectedCluster?: Cluster;
|
||||
|
||||
@property() private _bindableDevices: ZHADevice[] = [];
|
||||
|
||||
@property() private _groups: ZHAGroup[] = [];
|
||||
|
||||
public async showDialog(
|
||||
params: ZHADeviceZigbeeInfoDialogParams
|
||||
): Promise<void> {
|
||||
this._device = params.device;
|
||||
}
|
||||
|
||||
protected updated(changedProperties: PropertyValues): void {
|
||||
super.update(changedProperties);
|
||||
if (changedProperties.has("_device")) {
|
||||
this._fetchData();
|
||||
}
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this._device) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
hideActions
|
||||
@closing="${this._close}"
|
||||
.heading=${createCloseHeading(
|
||||
this.hass,
|
||||
this.hass.localize("ui.panel.config.zha.clusters.header")
|
||||
)}
|
||||
>
|
||||
<zha-clusters
|
||||
.hass=${this.hass}
|
||||
.selectedDevice="${this._device}"
|
||||
@zha-cluster-selected="${this._onClusterSelected}"
|
||||
></zha-clusters>
|
||||
${this._selectedCluster
|
||||
? html`
|
||||
<zha-cluster-attributes
|
||||
.hass=${this.hass}
|
||||
.selectedNode="${this._device}"
|
||||
.selectedCluster="${this._selectedCluster}"
|
||||
></zha-cluster-attributes>
|
||||
<zha-cluster-commands
|
||||
.hass=${this.hass}
|
||||
.selectedNode="${this._device}"
|
||||
.selectedCluster="${this._selectedCluster}"
|
||||
></zha-cluster-commands>
|
||||
`
|
||||
: ""}
|
||||
${this._bindableDevices.length > 0
|
||||
? html`
|
||||
<zha-device-binding-control
|
||||
.hass=${this.hass}
|
||||
.selectedDevice="${this._device}"
|
||||
.bindableDevices="${this._bindableDevices}"
|
||||
></zha-device-binding-control>
|
||||
`
|
||||
: ""}
|
||||
${this._device && this._groups.length > 0
|
||||
? html`
|
||||
<zha-group-binding-control
|
||||
.hass=${this.hass}
|
||||
.selectedDevice="${this._device}"
|
||||
.groups="${this._groups}"
|
||||
></zha-group-binding-control>
|
||||
`
|
||||
: ""}
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _onClusterSelected(
|
||||
selectedClusterEvent: HASSDomEvent<ZHAClusterSelectedParams>
|
||||
): void {
|
||||
this._selectedCluster = selectedClusterEvent.detail.cluster;
|
||||
}
|
||||
|
||||
private _close(): void {
|
||||
this._device = undefined;
|
||||
}
|
||||
|
||||
private async _fetchData(): Promise<void> {
|
||||
if (this._device && this.hass) {
|
||||
this._bindableDevices =
|
||||
this._device && this._device.device_type !== "Coordinator"
|
||||
? (await fetchBindableDevices(this.hass, this._device.ieee)).sort(
|
||||
sortZHADevices
|
||||
)
|
||||
: [];
|
||||
this._groups = (await fetchGroups(this.hass!)).sort(sortZHAGroups);
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return haStyleDialog;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"dialog-zha-cluster": DialogZHACluster;
|
||||
}
|
||||
}
|
@ -6,10 +6,10 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import "../../components/ha-code-editor";
|
||||
import { createCloseHeading } from "../../components/ha-dialog";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import "../../../../../components/ha-code-editor";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
import { haStyleDialog } from "../../../../../resources/styles";
|
||||
import { HomeAssistant } from "../../../../../types";
|
||||
import { ZHADeviceZigbeeInfoDialogParams } from "./show-dialog-zha-device-zigbee-info";
|
||||
|
||||
@customElement("dialog-zha-device-zigbee-info")
|
@ -0,0 +1,22 @@
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { ZHADevice } from "../../../../../data/zha";
|
||||
|
||||
export interface ZHAClusterDialogParams {
|
||||
device: ZHADevice;
|
||||
}
|
||||
|
||||
export const loadZHAClusterDialog = () =>
|
||||
import(
|
||||
/* webpackChunkName: "dialog-zha-device-zigbee-info" */ "./dialog-zha-cluster"
|
||||
);
|
||||
|
||||
export const showZHAClusterDialog = (
|
||||
element: HTMLElement,
|
||||
params: ZHAClusterDialogParams
|
||||
): void => {
|
||||
fireEvent(element, "show-dialog", {
|
||||
dialogTag: "dialog-zha-cluster",
|
||||
dialogImport: loadZHAClusterDialog,
|
||||
dialogParams: params,
|
||||
});
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { ZHADevice } from "../../data/zha";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { ZHADevice } from "../../../../../data/zha";
|
||||
|
||||
export interface ZHADeviceZigbeeInfoDialogParams {
|
||||
device: ZHADevice;
|
@ -64,9 +64,6 @@ export class ZHAClusters extends LitElement {
|
||||
return html`
|
||||
<ha-config-section .isWide="${this.isWide}">
|
||||
<div class="header" slot="header">
|
||||
<span>
|
||||
${this.hass!.localize("ui.panel.config.zha.clusters.header")}
|
||||
</span>
|
||||
<ha-icon-button
|
||||
class="toggle-help-icon"
|
||||
@click="${this._onHelpTap}"
|
||||
|
@ -38,6 +38,10 @@ class HaConfigZwave extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style ha-form-style">
|
||||
app-toolbar {
|
||||
border-bottom: 1px solid var(--divider-color);
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
@ -53,8 +53,7 @@ class HaConfigScene extends HassRouterPage {
|
||||
|
||||
private _getScenes = memoizeOne((states: HassEntities): SceneEntity[] => {
|
||||
return Object.values(states).filter(
|
||||
(entity) =>
|
||||
computeStateDomain(entity) === "scene" && !entity.attributes.hidden
|
||||
(entity) => computeStateDomain(entity) === "scene"
|
||||
) as SceneEntity[];
|
||||
});
|
||||
|
||||
|
@ -53,8 +53,7 @@ class HaConfigScript extends HassRouterPage {
|
||||
|
||||
private _getScripts = memoizeOne((states: HassEntities): ScriptEntity[] => {
|
||||
return Object.values(states).filter(
|
||||
(entity) =>
|
||||
computeStateDomain(entity) === "script" && !entity.attributes.hidden
|
||||
(entity) => computeStateDomain(entity) === "script"
|
||||
) as ScriptEntity[];
|
||||
});
|
||||
|
||||
|
@ -25,7 +25,7 @@ import { checkCoreConfig } from "../../../data/core";
|
||||
const reloadableDomains = [
|
||||
"group",
|
||||
"automation",
|
||||
"scripts",
|
||||
"script",
|
||||
"scene",
|
||||
"person",
|
||||
"zone",
|
||||
|
@ -25,10 +25,6 @@ class DeveloperToolsRouter extends HassRouterPage {
|
||||
tag: "developer-tools-event",
|
||||
load: () => import("./event/developer-tools-event"),
|
||||
},
|
||||
mqtt: {
|
||||
tag: "developer-tools-mqtt",
|
||||
load: () => import("./mqtt/developer-tools-mqtt"),
|
||||
},
|
||||
service: {
|
||||
tag: "developer-tools-service",
|
||||
load: () => import("./service/developer-tools-service"),
|
||||
|
@ -13,7 +13,6 @@ import {
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import scrollToTarget from "../../common/dom/scroll-to-target";
|
||||
import { navigate } from "../../common/navigate";
|
||||
import "../../components/ha-menu-button";
|
||||
@ -72,15 +71,6 @@ class PanelDeveloperTools extends LitElement {
|
||||
"ui.panel.developer-tools.tabs.events.title"
|
||||
)}
|
||||
</paper-tab>
|
||||
${isComponentLoaded(this.hass, "mqtt")
|
||||
? html`
|
||||
<paper-tab page-name="mqtt">
|
||||
${this.hass.localize(
|
||||
"ui.panel.developer-tools.tabs.mqtt.title"
|
||||
)}
|
||||
</paper-tab>
|
||||
`
|
||||
: ""}
|
||||
</paper-tabs>
|
||||
</app-header>
|
||||
<developer-tools-router
|
||||
|
@ -1,215 +0,0 @@
|
||||
import "@polymer/app-layout/app-header-layout/app-header-layout";
|
||||
import "@polymer/app-layout/app-header/app-header";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
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";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import "@vaadin/vaadin-date-picker/theme/material/vaadin-date-picker";
|
||||
import { formatDate } from "../../common/datetime/format_date";
|
||||
import { computeRTL } from "../../common/util/compute_rtl";
|
||||
import "../../components/ha-menu-button";
|
||||
import "../../components/state-history-charts";
|
||||
import "../../data/ha-state-history-data";
|
||||
import LocalizeMixin from "../../mixins/localize-mixin";
|
||||
import "../../resources/ha-date-picker-style";
|
||||
import "../../styles/polymer-ha-style";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class HaPanelHistory extends LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
|
||||
vaadin-date-picker {
|
||||
margin-right: 16px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
paper-dropdown-menu {
|
||||
max-width: 100px;
|
||||
margin-right: 16px;
|
||||
margin-top: 5px;
|
||||
--paper-input-container-label-floating: {
|
||||
padding-bottom: 11px;
|
||||
}
|
||||
--paper-input-suffix: {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
:host([rtl]) paper-dropdown-menu {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-state-history-data
|
||||
hass="[[hass]]"
|
||||
filter-type="[[_filterType]]"
|
||||
start-time="[[_computeStartTime(_currentDate)]]"
|
||||
end-time="[[endTime]]"
|
||||
data="{{stateHistory}}"
|
||||
is-loading="{{isLoadingData}}"
|
||||
></ha-state-history-data>
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-menu-button
|
||||
hass="[[hass]]"
|
||||
narrow="[[narrow]]"
|
||||
></ha-menu-button>
|
||||
<div main-title>[[localize('panel.history')]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class="flex content">
|
||||
<div class="flex layout horizontal wrap">
|
||||
<vaadin-date-picker
|
||||
id="picker"
|
||||
value="{{_currentDate}}"
|
||||
label="[[localize('ui.panel.history.showing_entries')]]"
|
||||
disabled="[[isLoadingData]]"
|
||||
required
|
||||
></vaadin-date-picker>
|
||||
|
||||
<paper-dropdown-menu
|
||||
label-float
|
||||
label="[[localize('ui.panel.history.period')]]"
|
||||
disabled="[[isLoadingData]]"
|
||||
>
|
||||
<paper-listbox
|
||||
slot="dropdown-content"
|
||||
selected="{{_periodIndex}}"
|
||||
>
|
||||
<paper-item
|
||||
>[[localize('ui.duration.day', 'count', 1)]]</paper-item
|
||||
>
|
||||
<paper-item
|
||||
>[[localize('ui.duration.day', 'count', 3)]]</paper-item
|
||||
>
|
||||
<paper-item
|
||||
>[[localize('ui.duration.week', 'count', 1)]]</paper-item
|
||||
>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
</div>
|
||||
<state-history-charts
|
||||
hass="[[hass]]"
|
||||
history-data="[[stateHistory]]"
|
||||
is-loading-data="[[isLoadingData]]"
|
||||
end-time="[[endTime]]"
|
||||
no-single
|
||||
>
|
||||
</state-history-charts>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
narrow: Boolean,
|
||||
|
||||
stateHistory: {
|
||||
type: Object,
|
||||
value: null,
|
||||
},
|
||||
|
||||
_periodIndex: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
|
||||
isLoadingData: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
endTime: {
|
||||
type: Object,
|
||||
computed: "_computeEndTime(_currentDate, _periodIndex)",
|
||||
},
|
||||
|
||||
// ISO8601 formatted date string
|
||||
_currentDate: {
|
||||
type: String,
|
||||
value: function () {
|
||||
var value = new Date();
|
||||
var today = new Date(
|
||||
Date.UTC(value.getFullYear(), value.getMonth(), value.getDate())
|
||||
);
|
||||
return today.toISOString().split("T")[0];
|
||||
},
|
||||
},
|
||||
|
||||
_filterType: {
|
||||
type: String,
|
||||
value: "date",
|
||||
},
|
||||
|
||||
rtl: {
|
||||
type: Boolean,
|
||||
reflectToAttribute: true,
|
||||
computed: "_computeRTL(hass)",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
datepickerFocus() {
|
||||
this.datePicker.adjustPosition();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
// We are unable to parse date because we use intl api to render date
|
||||
this.$.picker.set("i18n.parseDate", null);
|
||||
this.$.picker.set("i18n.formatDate", (date) =>
|
||||
formatDate(new Date(date.year, date.month, date.day), this.hass.language)
|
||||
);
|
||||
}
|
||||
|
||||
_computeStartTime(_currentDate) {
|
||||
if (!_currentDate) return undefined;
|
||||
var parts = _currentDate.split("-");
|
||||
parts[1] = parseInt(parts[1]) - 1;
|
||||
return new Date(parts[0], parts[1], parts[2]);
|
||||
}
|
||||
|
||||
_computeEndTime(_currentDate, periodIndex) {
|
||||
var startTime = this._computeStartTime(_currentDate);
|
||||
var endTime = new Date(startTime);
|
||||
endTime.setDate(startTime.getDate() + this._computeFilterDays(periodIndex));
|
||||
return endTime;
|
||||
}
|
||||
|
||||
_computeFilterDays(periodIndex) {
|
||||
switch (periodIndex) {
|
||||
case 1:
|
||||
return 3;
|
||||
case 2:
|
||||
return 7;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
_computeRTL(hass) {
|
||||
return computeRTL(hass);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-panel-history", HaPanelHistory);
|
204
src/panels/history/ha-panel-history.ts
Normal file
204
src/panels/history/ha-panel-history.ts
Normal file
@ -0,0 +1,204 @@
|
||||
import "@polymer/app-layout/app-header-layout/app-header-layout";
|
||||
import "@polymer/app-layout/app-header/app-header";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import { computeRTL } from "../../common/util/compute_rtl";
|
||||
import "../../components/ha-menu-button";
|
||||
import "../../components/state-history-charts";
|
||||
import { LitElement, css, property, PropertyValues } from "lit-element";
|
||||
import { html } from "lit-html";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import type { DateRangePickerRanges } from "../../components/ha-date-range-picker";
|
||||
import "../../components/ha-date-range-picker";
|
||||
import { fetchDate, computeHistory } from "../../data/history";
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
|
||||
class HaPanelHistory extends LitElement {
|
||||
@property() hass!: HomeAssistant;
|
||||
|
||||
@property({ reflect: true, type: Boolean }) narrow!: boolean;
|
||||
|
||||
@property() _startDate: Date;
|
||||
|
||||
@property() _endDate: Date;
|
||||
|
||||
@property() _entityId = "";
|
||||
|
||||
@property() _isLoading = false;
|
||||
|
||||
@property() _stateHistory?;
|
||||
|
||||
@property({ reflect: true, type: Boolean }) rtl = false;
|
||||
|
||||
@property() private _ranges?: DateRangePickerRanges;
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
const start = new Date();
|
||||
start.setHours(start.getHours() - 2);
|
||||
start.setMinutes(0);
|
||||
start.setSeconds(0);
|
||||
this._startDate = start;
|
||||
|
||||
const end = new Date();
|
||||
end.setHours(end.getHours() + 1);
|
||||
end.setMinutes(0);
|
||||
end.setSeconds(0);
|
||||
this._endDate = end;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-menu-button
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
></ha-menu-button>
|
||||
<div main-title>${this.hass.localize("panel.history")}</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class="flex content">
|
||||
<div class="flex layout horizontal wrap">
|
||||
<ha-date-range-picker
|
||||
.hass=${this.hass}
|
||||
?disabled=${this._isLoading}
|
||||
.startDate=${this._startDate}
|
||||
.endDate=${this._endDate}
|
||||
.ranges=${this._ranges}
|
||||
@change=${this._dateRangeChanged}
|
||||
></ha-date-range-picker>
|
||||
</div>
|
||||
${this._isLoading
|
||||
? html`<paper-spinner
|
||||
active
|
||||
alt=${this.hass.localize("ui.common.loading")}
|
||||
></paper-spinner>`
|
||||
: html`
|
||||
<state-history-charts
|
||||
.hass=${this.hass}
|
||||
.historyData=${this._stateHistory}
|
||||
.endTime=${this._endDate}
|
||||
no-single
|
||||
>
|
||||
</state-history-charts>
|
||||
`}
|
||||
</div>
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
const todayEnd = new Date(today);
|
||||
todayEnd.setDate(todayEnd.getDate() + 1);
|
||||
todayEnd.setMilliseconds(todayEnd.getMilliseconds() - 1);
|
||||
|
||||
const todayCopy = new Date(today);
|
||||
|
||||
const yesterday = new Date(todayCopy.setDate(today.getDate() - 1));
|
||||
const yesterdayEnd = new Date(yesterday);
|
||||
yesterdayEnd.setDate(yesterdayEnd.getDate() + 1);
|
||||
yesterdayEnd.setMilliseconds(yesterdayEnd.getMilliseconds() - 1);
|
||||
|
||||
const thisWeekStart = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay())
|
||||
);
|
||||
const thisWeekEnd = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay() + 7)
|
||||
);
|
||||
thisWeekEnd.setMilliseconds(thisWeekEnd.getMilliseconds() - 1);
|
||||
|
||||
const lastWeekStart = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay() - 7)
|
||||
);
|
||||
const lastWeekEnd = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay())
|
||||
);
|
||||
lastWeekEnd.setMilliseconds(lastWeekEnd.getMilliseconds() - 1);
|
||||
|
||||
this._ranges = {
|
||||
[this.hass.localize("ui.panel.history.ranges.today")]: [today, todayEnd],
|
||||
[this.hass.localize("ui.panel.history.ranges.yesterday")]: [
|
||||
yesterday,
|
||||
yesterdayEnd,
|
||||
],
|
||||
[this.hass.localize("ui.panel.history.ranges.this_week")]: [
|
||||
thisWeekStart,
|
||||
thisWeekEnd,
|
||||
],
|
||||
[this.hass.localize("ui.panel.history.ranges.last_week")]: [
|
||||
lastWeekStart,
|
||||
lastWeekEnd,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
if (
|
||||
changedProps.has("_startDate") ||
|
||||
changedProps.has("_endDate") ||
|
||||
changedProps.has("_entityId")
|
||||
) {
|
||||
this._getHistory();
|
||||
}
|
||||
|
||||
if (changedProps.has("hass")) {
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
if (!oldHass || oldHass.language !== this.hass.language) {
|
||||
this.rtl = computeRTL(this.hass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async _getHistory() {
|
||||
this._isLoading = true;
|
||||
const dateHistory = await fetchDate(
|
||||
this.hass,
|
||||
this._startDate,
|
||||
this._endDate
|
||||
);
|
||||
this._stateHistory = computeHistory(
|
||||
this.hass,
|
||||
dateHistory,
|
||||
this.hass.localize,
|
||||
this.hass.language
|
||||
);
|
||||
this._isLoading = false;
|
||||
}
|
||||
|
||||
private _dateRangeChanged(ev) {
|
||||
this._startDate = ev.detail.startDate;
|
||||
const endDate = ev.detail.endDate;
|
||||
if (endDate.getHours() === 0 && endDate.getMinutes() === 0) {
|
||||
endDate.setDate(endDate.getDate() + 1);
|
||||
endDate.setMilliseconds(endDate.getMilliseconds() - 1);
|
||||
}
|
||||
this._endDate = endDate;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
.content {
|
||||
padding: 0 16px 16px;
|
||||
}
|
||||
paper-spinner {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-panel-history", HaPanelHistory);
|
@ -1,120 +0,0 @@
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
|
||||
const DATA_CACHE = {};
|
||||
const ALL_ENTITIES = "*";
|
||||
|
||||
class HaLogbookData extends PolymerElement {
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
observer: "hassChanged",
|
||||
},
|
||||
|
||||
filterDate: {
|
||||
type: String,
|
||||
observer: "filterDataChanged",
|
||||
},
|
||||
|
||||
filterPeriod: {
|
||||
type: Number,
|
||||
observer: "filterDataChanged",
|
||||
},
|
||||
|
||||
filterEntity: {
|
||||
type: String,
|
||||
observer: "filterDataChanged",
|
||||
},
|
||||
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
readOnly: true,
|
||||
notify: true,
|
||||
},
|
||||
|
||||
entries: {
|
||||
type: Object,
|
||||
value: null,
|
||||
readOnly: true,
|
||||
notify: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
hassChanged(newHass, oldHass) {
|
||||
if (!oldHass && this.filterDate) {
|
||||
this.updateData();
|
||||
}
|
||||
}
|
||||
|
||||
filterDataChanged(newValue, oldValue) {
|
||||
if (oldValue !== undefined) {
|
||||
this.updateData();
|
||||
}
|
||||
}
|
||||
|
||||
updateData() {
|
||||
if (!this.hass) return;
|
||||
|
||||
this._setIsLoading(true);
|
||||
|
||||
this.getData(this.filterDate, this.filterPeriod, this.filterEntity).then(
|
||||
(logbookEntries) => {
|
||||
this._setEntries(logbookEntries);
|
||||
this._setIsLoading(false);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
getData(date, period, entityId) {
|
||||
if (!entityId) entityId = ALL_ENTITIES;
|
||||
|
||||
if (!DATA_CACHE[period]) DATA_CACHE[period] = [];
|
||||
if (!DATA_CACHE[period][date]) DATA_CACHE[period][date] = [];
|
||||
|
||||
if (DATA_CACHE[period][date][entityId]) {
|
||||
return DATA_CACHE[period][date][entityId];
|
||||
}
|
||||
|
||||
if (entityId !== ALL_ENTITIES && DATA_CACHE[period][date][ALL_ENTITIES]) {
|
||||
return DATA_CACHE[period][date][ALL_ENTITIES].then(function (entities) {
|
||||
return entities.filter(function (entity) {
|
||||
return entity.entity_id === entityId;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
DATA_CACHE[period][date][entityId] = this._getFromServer(
|
||||
date,
|
||||
period,
|
||||
entityId
|
||||
);
|
||||
return DATA_CACHE[period][date][entityId];
|
||||
}
|
||||
|
||||
_getFromServer(date, period, entityId) {
|
||||
let url = "logbook/" + date + "?period=" + period;
|
||||
if (entityId !== ALL_ENTITIES) {
|
||||
url += "&entity=" + entityId;
|
||||
}
|
||||
|
||||
return this.hass.callApi("GET", url).then(
|
||||
function (logbookEntries) {
|
||||
logbookEntries.reverse();
|
||||
return logbookEntries;
|
||||
},
|
||||
function () {
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
refreshLogbook() {
|
||||
DATA_CACHE[this.filterPeriod][this.filterDate] = [];
|
||||
this.updateData();
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-logbook-data", HaLogbookData);
|
@ -9,6 +9,7 @@ import {
|
||||
} from "lit-element";
|
||||
import { scroll } from "lit-virtualizer";
|
||||
import { formatDate } from "../../common/datetime/format_date";
|
||||
import { fetchUsers } from "../../data/user";
|
||||
import { formatTimeWithSeconds } from "../../common/datetime/format_time";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { domainIcon } from "../../common/entity/domain_icon";
|
||||
@ -21,6 +22,9 @@ import { HomeAssistant } from "../../types";
|
||||
class HaLogbook extends LitElement {
|
||||
@property() public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
private _userid_to_name = {};
|
||||
|
||||
@property() public entries: LogbookEntry[] = [];
|
||||
|
||||
@property({ attribute: "rtl", type: Boolean, reflect: true })
|
||||
@ -58,6 +62,20 @@ class HaLogbook extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private async _fetchUsers() {
|
||||
const users = await fetchUsers(this.hass);
|
||||
const userid_to_name = {};
|
||||
users.forEach((user) => {
|
||||
userid_to_name[user.id] = user.name;
|
||||
});
|
||||
this._userid_to_name = userid_to_name;
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProperties: PropertyValues) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this._fetchUsers();
|
||||
}
|
||||
|
||||
private _renderLogbookItem(
|
||||
item: LogbookEntry,
|
||||
index?: number
|
||||
@ -67,6 +85,8 @@ class HaLogbook extends LitElement {
|
||||
}
|
||||
const previous = this.entries[index - 1];
|
||||
const state = item.entity_id ? this.hass.states[item.entity_id] : undefined;
|
||||
const item_username =
|
||||
item.context_user_id && this._userid_to_name[item.context_user_id];
|
||||
return html`
|
||||
<div>
|
||||
${index === 0 ||
|
||||
@ -101,7 +121,11 @@ class HaLogbook extends LitElement {
|
||||
${item.name}
|
||||
</a>
|
||||
`}
|
||||
<span>${item.message}</span>
|
||||
<span
|
||||
>${item.message}${item_username
|
||||
? ` (${item_username})`
|
||||
: ``}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,283 +0,0 @@
|
||||
import "@polymer/app-layout/app-header-layout/app-header-layout";
|
||||
import "@polymer/app-layout/app-header/app-header";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import "../../components/ha-icon-button";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||
/* eslint-plugin-disable lit */
|
||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||
import "@vaadin/vaadin-date-picker/theme/material/vaadin-date-picker";
|
||||
import { formatDate } from "../../common/datetime/format_date";
|
||||
import { computeRTL } from "../../common/util/compute_rtl";
|
||||
import "../../components/entity/ha-entity-picker";
|
||||
import "../../components/ha-menu-button";
|
||||
import LocalizeMixin from "../../mixins/localize-mixin";
|
||||
import "../../resources/ha-date-picker-style";
|
||||
import "../../styles/polymer-ha-style";
|
||||
import "./ha-logbook";
|
||||
import "./ha-logbook-data";
|
||||
|
||||
/*
|
||||
* @appliesMixin LocalizeMixin
|
||||
*/
|
||||
class HaPanelLogbook extends LocalizeMixin(PolymerElement) {
|
||||
static get template() {
|
||||
return html`
|
||||
<style include="ha-style">
|
||||
ha-logbook {
|
||||
height: calc(100vh - 136px);
|
||||
}
|
||||
|
||||
:host([narrow]) ha-logbook {
|
||||
height: calc(100vh - 198px);
|
||||
}
|
||||
|
||||
paper-spinner {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wrap {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
:host([narrow]) .filters {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
vaadin-date-picker {
|
||||
max-width: 200px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
:host([rtl]) vaadin-date-picker {
|
||||
margin-right: 0;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
paper-dropdown-menu {
|
||||
max-width: 100px;
|
||||
margin-right: 16px;
|
||||
--paper-input-container-label-floating: {
|
||||
padding-bottom: 11px;
|
||||
}
|
||||
--paper-input-suffix: {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
:host([rtl]) paper-dropdown-menu {
|
||||
text-align: right;
|
||||
margin-right: 0;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
ha-entity-picker {
|
||||
display: inline-block;
|
||||
flex-grow: 1;
|
||||
max-width: 400px;
|
||||
--paper-input-suffix: {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
:host([narrow]) ha-entity-picker {
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<ha-logbook-data
|
||||
hass="[[hass]]"
|
||||
is-loading="{{isLoading}}"
|
||||
entries="{{entries}}"
|
||||
filter-date="[[_computeFilterDate(_currentDate)]]"
|
||||
filter-period="[[_computeFilterDays(_periodIndex)]]"
|
||||
filter-entity="[[entityId]]"
|
||||
></ha-logbook-data>
|
||||
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-menu-button
|
||||
hass="[[hass]]"
|
||||
narrow="[[narrow]]"
|
||||
></ha-menu-button>
|
||||
<div main-title>[[localize('panel.logbook')]]</div>
|
||||
<ha-icon-button
|
||||
icon="hass:refresh"
|
||||
on-click="refreshLogbook"
|
||||
hidden$="[[isLoading]]"
|
||||
></ha-icon-button>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<paper-spinner
|
||||
active="[[isLoading]]"
|
||||
hidden$="[[!isLoading]]"
|
||||
alt="[[localize('ui.common.loading')]]"
|
||||
></paper-spinner>
|
||||
|
||||
<div class="filters">
|
||||
<vaadin-date-picker
|
||||
id="picker"
|
||||
value="{{_currentDate}}"
|
||||
label="[[localize('ui.panel.logbook.showing_entries')]]"
|
||||
disabled="[[isLoading]]"
|
||||
required
|
||||
></vaadin-date-picker>
|
||||
|
||||
<paper-dropdown-menu
|
||||
label-float
|
||||
label="[[localize('ui.panel.logbook.period')]]"
|
||||
disabled="[[isLoading]]"
|
||||
>
|
||||
<paper-listbox slot="dropdown-content" selected="{{_periodIndex}}">
|
||||
<paper-item
|
||||
>[[localize('ui.duration.day', 'count', 1)]]</paper-item
|
||||
>
|
||||
<paper-item
|
||||
>[[localize('ui.duration.day', 'count', 3)]]</paper-item
|
||||
>
|
||||
<paper-item
|
||||
>[[localize('ui.duration.week', 'count', 1)]]</paper-item
|
||||
>
|
||||
</paper-listbox>
|
||||
</paper-dropdown-menu>
|
||||
|
||||
<ha-entity-picker
|
||||
hass="[[hass]]"
|
||||
value="{{_entityId}}"
|
||||
label="[[localize('ui.components.entity.entity-picker.entity')]]"
|
||||
disabled="[[isLoading]]"
|
||||
on-change="_entityPicked"
|
||||
></ha-entity-picker>
|
||||
</div>
|
||||
|
||||
<ha-logbook
|
||||
hass="[[hass]]"
|
||||
entries="[[entries]]"
|
||||
hidden$="[[isLoading]]"
|
||||
></ha-logbook>
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
|
||||
narrow: { type: Boolean, reflectToAttribute: true },
|
||||
|
||||
// ISO8601 formatted date string
|
||||
_currentDate: {
|
||||
type: String,
|
||||
value: function () {
|
||||
const value = new Date();
|
||||
const today = new Date(
|
||||
Date.UTC(value.getFullYear(), value.getMonth(), value.getDate())
|
||||
);
|
||||
return today.toISOString().split("T")[0];
|
||||
},
|
||||
},
|
||||
|
||||
_periodIndex: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
|
||||
_entityId: {
|
||||
type: String,
|
||||
value: "",
|
||||
},
|
||||
|
||||
entityId: {
|
||||
type: String,
|
||||
value: "",
|
||||
readOnly: true,
|
||||
},
|
||||
|
||||
isLoading: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
entries: {
|
||||
type: Array,
|
||||
},
|
||||
|
||||
datePicker: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
rtl: {
|
||||
type: Boolean,
|
||||
reflectToAttribute: true,
|
||||
computed: "_computeRTL(hass)",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
ready() {
|
||||
super.ready();
|
||||
this.hass.loadBackendTranslation("title");
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
// We are unable to parse date because we use intl api to render date
|
||||
this.$.picker.set("i18n.parseDate", null);
|
||||
this.$.picker.set("i18n.formatDate", (date) =>
|
||||
formatDate(new Date(date.year, date.month, date.day), this.hass.language)
|
||||
);
|
||||
}
|
||||
|
||||
_computeFilterDate(_currentDate) {
|
||||
if (!_currentDate) return undefined;
|
||||
var parts = _currentDate.split("-");
|
||||
parts[1] = parseInt(parts[1]) - 1;
|
||||
return new Date(parts[0], parts[1], parts[2]).toISOString();
|
||||
}
|
||||
|
||||
_computeFilterDays(periodIndex) {
|
||||
switch (periodIndex) {
|
||||
case 1:
|
||||
return 3;
|
||||
case 2:
|
||||
return 7;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
_entityPicked(ev) {
|
||||
this._setEntityId(ev.target.value);
|
||||
}
|
||||
|
||||
refreshLogbook() {
|
||||
this.shadowRoot.querySelector("ha-logbook-data").refreshLogbook();
|
||||
}
|
||||
|
||||
_computeRTL(hass) {
|
||||
return computeRTL(hass);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ha-panel-logbook", HaPanelLogbook);
|
279
src/panels/logbook/ha-panel-logbook.ts
Normal file
279
src/panels/logbook/ha-panel-logbook.ts
Normal file
@ -0,0 +1,279 @@
|
||||
import "@polymer/app-layout/app-header-layout/app-header-layout";
|
||||
import "@polymer/app-layout/app-header/app-header";
|
||||
import "@polymer/app-layout/app-toolbar/app-toolbar";
|
||||
import "../../components/ha-icon-button";
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
import { computeRTL } from "../../common/util/compute_rtl";
|
||||
import "../../components/entity/ha-entity-picker";
|
||||
import "../../components/ha-menu-button";
|
||||
import "./ha-logbook";
|
||||
import {
|
||||
LitElement,
|
||||
property,
|
||||
customElement,
|
||||
html,
|
||||
css,
|
||||
PropertyValues,
|
||||
} from "lit-element";
|
||||
import { HomeAssistant } from "../../types";
|
||||
import { haStyle } from "../../resources/styles";
|
||||
import {
|
||||
clearLogbookCache,
|
||||
getLogbookData,
|
||||
LogbookEntry,
|
||||
} from "../../data/logbook";
|
||||
import { mdiRefresh } from "@mdi/js";
|
||||
import "../../components/ha-date-range-picker";
|
||||
import type { DateRangePickerRanges } from "../../components/ha-date-range-picker";
|
||||
|
||||
@customElement("ha-panel-logbook")
|
||||
export class HaPanelLogbook extends LitElement {
|
||||
@property() hass!: HomeAssistant;
|
||||
|
||||
@property({ reflect: true, type: Boolean }) narrow!: boolean;
|
||||
|
||||
@property() _startDate: Date;
|
||||
|
||||
@property() _endDate: Date;
|
||||
|
||||
@property() _entityId = "";
|
||||
|
||||
@property() _isLoading = false;
|
||||
|
||||
@property() _entries: LogbookEntry[] = [];
|
||||
|
||||
@property({ reflect: true, type: Boolean }) rtl = false;
|
||||
|
||||
@property() private _ranges?: DateRangePickerRanges;
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
|
||||
const start = new Date();
|
||||
start.setHours(start.getHours() - 2);
|
||||
start.setMinutes(0);
|
||||
start.setSeconds(0);
|
||||
this._startDate = start;
|
||||
|
||||
const end = new Date();
|
||||
end.setHours(end.getHours() + 1);
|
||||
end.setMinutes(0);
|
||||
end.setSeconds(0);
|
||||
this._endDate = end;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
return html`
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
<app-toolbar>
|
||||
<ha-menu-button
|
||||
.hass=${this.hass}
|
||||
.narrow=${this.narrow}
|
||||
></ha-menu-button>
|
||||
<div main-title>${this.hass.localize("panel.logbook")}</div>
|
||||
<mwc-icon-button
|
||||
@click=${this._refreshLogbook}
|
||||
.disabled=${this._isLoading}
|
||||
>
|
||||
<ha-svg-icon path=${mdiRefresh}></ha-svg-icon>
|
||||
</mwc-icon-button>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
${this._isLoading ? html`` : ""}
|
||||
|
||||
<div class="filters">
|
||||
<ha-date-range-picker
|
||||
.hass=${this.hass}
|
||||
?disabled=${this._isLoading}
|
||||
.startDate=${this._startDate}
|
||||
.endDate=${this._endDate}
|
||||
.ranges=${this._ranges}
|
||||
@change=${this._dateRangeChanged}
|
||||
></ha-date-range-picker>
|
||||
|
||||
<ha-entity-picker
|
||||
.hass=${this.hass}
|
||||
.value=${this._entityId}
|
||||
.label=${this.hass.localize(
|
||||
"ui.components.entity.entity-picker.entity"
|
||||
)}
|
||||
.disabled=${this._isLoading}
|
||||
@change=${this._entityPicked}
|
||||
></ha-entity-picker>
|
||||
</div>
|
||||
|
||||
${this._isLoading
|
||||
? html`<paper-spinner
|
||||
active
|
||||
alt=${this.hass.localize("ui.common.loading")}
|
||||
></paper-spinner>`
|
||||
: html`<ha-logbook
|
||||
.hass=${this.hass}
|
||||
.entries=${this._entries}
|
||||
></ha-logbook>`}
|
||||
</app-header-layout>
|
||||
`;
|
||||
}
|
||||
|
||||
protected firstUpdated(changedProps: PropertyValues) {
|
||||
super.firstUpdated(changedProps);
|
||||
this.hass.loadBackendTranslation("title");
|
||||
|
||||
const today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
const todayEnd = new Date(today);
|
||||
todayEnd.setDate(todayEnd.getDate() + 1);
|
||||
todayEnd.setMilliseconds(todayEnd.getMilliseconds() - 1);
|
||||
|
||||
const todayCopy = new Date(today);
|
||||
|
||||
const yesterday = new Date(todayCopy.setDate(today.getDate() - 1));
|
||||
const yesterdayEnd = new Date(yesterday);
|
||||
yesterdayEnd.setDate(yesterdayEnd.getDate() + 1);
|
||||
yesterdayEnd.setMilliseconds(yesterdayEnd.getMilliseconds() - 1);
|
||||
|
||||
const thisWeekStart = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay())
|
||||
);
|
||||
const thisWeekEnd = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay() + 7)
|
||||
);
|
||||
thisWeekEnd.setMilliseconds(thisWeekEnd.getMilliseconds() - 1);
|
||||
|
||||
const lastWeekStart = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay() - 7)
|
||||
);
|
||||
const lastWeekEnd = new Date(
|
||||
todayCopy.setDate(today.getDate() - today.getDay())
|
||||
);
|
||||
lastWeekEnd.setMilliseconds(lastWeekEnd.getMilliseconds() - 1);
|
||||
|
||||
this._ranges = {
|
||||
[this.hass.localize("ui.panel.logbook.ranges.today")]: [today, todayEnd],
|
||||
[this.hass.localize("ui.panel.logbook.ranges.yesterday")]: [
|
||||
yesterday,
|
||||
yesterdayEnd,
|
||||
],
|
||||
[this.hass.localize("ui.panel.logbook.ranges.this_week")]: [
|
||||
thisWeekStart,
|
||||
thisWeekEnd,
|
||||
],
|
||||
[this.hass.localize("ui.panel.logbook.ranges.last_week")]: [
|
||||
lastWeekStart,
|
||||
lastWeekEnd,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues) {
|
||||
if (
|
||||
changedProps.has("_startDate") ||
|
||||
changedProps.has("_endDate") ||
|
||||
changedProps.has("_entityId")
|
||||
) {
|
||||
this._getData();
|
||||
}
|
||||
|
||||
if (changedProps.has("hass")) {
|
||||
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
|
||||
if (!oldHass || oldHass.language !== this.hass.language) {
|
||||
this.rtl = computeRTL(this.hass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _dateRangeChanged(ev) {
|
||||
this._startDate = ev.detail.startDate;
|
||||
const endDate = ev.detail.endDate;
|
||||
if (endDate.getHours() === 0 && endDate.getMinutes() === 0) {
|
||||
endDate.setDate(endDate.getDate() + 1);
|
||||
endDate.setMilliseconds(endDate.getMilliseconds() - 1);
|
||||
}
|
||||
this._endDate = endDate;
|
||||
}
|
||||
|
||||
private _entityPicked(ev) {
|
||||
this._entityId = ev.target.value;
|
||||
}
|
||||
|
||||
private _refreshLogbook() {
|
||||
this._entries = [];
|
||||
clearLogbookCache(
|
||||
this._startDate.toISOString(),
|
||||
this._endDate.toISOString()
|
||||
);
|
||||
this._getData();
|
||||
}
|
||||
|
||||
private async _getData() {
|
||||
this._isLoading = true;
|
||||
this._entries = await getLogbookData(
|
||||
this.hass,
|
||||
this._startDate.toISOString(),
|
||||
this._endDate.toISOString(),
|
||||
this._entityId
|
||||
);
|
||||
this._isLoading = false;
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return [
|
||||
haStyle,
|
||||
css`
|
||||
ha-logbook {
|
||||
height: calc(100vh - 136px);
|
||||
}
|
||||
|
||||
:host([narrow]) ha-logbook {
|
||||
height: calc(100vh - 198px);
|
||||
}
|
||||
|
||||
ha-date-range-picker {
|
||||
margin-right: 16px;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
:host([narrow]) ha-date-range-picker {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
paper-spinner {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wrap {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
:host([narrow]) .filters {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
ha-entity-picker {
|
||||
display: inline-block;
|
||||
flex-grow: 1;
|
||||
max-width: 400px;
|
||||
--paper-input-suffix: {
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
:host([narrow]) ha-entity-picker {
|
||||
max-width: none;
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
@ -228,6 +228,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
|
@ -12,7 +12,6 @@ import { classMap } from "lit-html/directives/class-map";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/state-history-charts";
|
||||
import { CacheConfig, getRecentWithCache } from "../../../data/cached-history";
|
||||
import "../../../data/ha-state-history-data";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { findEntities } from "../common/find-entites";
|
||||
import { processConfigEntities } from "../common/process-config-entities";
|
||||
|
@ -14,6 +14,7 @@ import "../cards/hui-weather-forecast-card";
|
||||
import {
|
||||
createLovelaceElement,
|
||||
getLovelaceElementClass,
|
||||
tryCreateLovelaceElement,
|
||||
} from "./create-element-base";
|
||||
|
||||
const ALWAYS_LOADED_TYPES = new Set([
|
||||
@ -52,6 +53,17 @@ const LAZY_LOAD_TYPES = {
|
||||
picture: () => import("../cards/hui-picture-card"),
|
||||
};
|
||||
|
||||
// This will not return an error card but will throw the error
|
||||
export const tryCreateCardElement = (config: LovelaceCardConfig) =>
|
||||
tryCreateLovelaceElement(
|
||||
"card",
|
||||
config,
|
||||
ALWAYS_LOADED_TYPES,
|
||||
LAZY_LOAD_TYPES,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
export const createCardElement = (config: LovelaceCardConfig) =>
|
||||
createLovelaceElement(
|
||||
"card",
|
||||
|
@ -73,15 +73,8 @@ const _createElement = <T extends keyof CreateElementConfigTypes>(
|
||||
const element = document.createElement(
|
||||
tag
|
||||
) as CreateElementConfigTypes[T]["element"];
|
||||
try {
|
||||
// @ts-ignore
|
||||
element.setConfig(config);
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.error(tag, err);
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
return _createErrorElement(err.message, config);
|
||||
}
|
||||
// @ts-ignore
|
||||
element.setConfig(config);
|
||||
return element;
|
||||
};
|
||||
|
||||
@ -152,9 +145,37 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||
domainTypes?: { _domain_not_found: string; [domain: string]: string },
|
||||
// Default type if no type given. If given, entity types will not work.
|
||||
defaultType?: string
|
||||
): CreateElementConfigTypes[T]["element"] | HuiErrorCard => {
|
||||
try {
|
||||
return tryCreateLovelaceElement(
|
||||
tagSuffix,
|
||||
config,
|
||||
alwaysLoadTypes,
|
||||
lazyLoadTypes,
|
||||
domainTypes,
|
||||
defaultType
|
||||
);
|
||||
} catch (err) {
|
||||
// eslint-disable-next-line
|
||||
console.error(tagSuffix, config.type, err);
|
||||
return _createErrorElement(err.message, config);
|
||||
}
|
||||
};
|
||||
|
||||
export const tryCreateLovelaceElement = <
|
||||
T extends keyof CreateElementConfigTypes
|
||||
>(
|
||||
tagSuffix: T,
|
||||
config: CreateElementConfigTypes[T]["config"],
|
||||
alwaysLoadTypes?: Set<string>,
|
||||
lazyLoadTypes?: { [domain: string]: () => Promise<unknown> },
|
||||
// Allow looking at "entity" in config and mapping that to a type
|
||||
domainTypes?: { _domain_not_found: string; [domain: string]: string },
|
||||
// Default type if no type given. If given, entity types will not work.
|
||||
defaultType?: string
|
||||
): CreateElementConfigTypes[T]["element"] | HuiErrorCard => {
|
||||
if (!config || typeof config !== "object") {
|
||||
return _createErrorElement("Config is not an object", config);
|
||||
throw new Error("Config is not an object");
|
||||
}
|
||||
|
||||
if (
|
||||
@ -163,7 +184,7 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||
// If domain types is given, we can derive a type from "entity"
|
||||
(!domainTypes || !("entity" in config))
|
||||
) {
|
||||
return _createErrorElement("No card type configured.", config);
|
||||
throw new Error("No card type configured.");
|
||||
}
|
||||
|
||||
const customTag = config.type ? _getCustomTag(config.type) : undefined;
|
||||
@ -185,7 +206,7 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||
}
|
||||
|
||||
if (type === undefined) {
|
||||
return _createErrorElement(`No type specified`, config);
|
||||
throw new Error("No type specified.");
|
||||
}
|
||||
|
||||
const tag = `hui-${type}-${tagSuffix}`;
|
||||
@ -199,7 +220,7 @@ export const createLovelaceElement = <T extends keyof CreateElementConfigTypes>(
|
||||
return _createElement(tag, config);
|
||||
}
|
||||
|
||||
return _createErrorElement(`Unknown type encountered: ${type}.`, config);
|
||||
throw new Error(`Unknown type encountered: ${type}`);
|
||||
};
|
||||
|
||||
export const getLovelaceElementClass = async <
|
||||
|
@ -158,6 +158,7 @@ export class HuiCardEditor extends LitElement {
|
||||
.error=${this._error}
|
||||
.rtl=${computeRTL(this.hass)}
|
||||
@value-changed=${this._handleYAMLChanged}
|
||||
@keydown=${this._ignoreKeydown}
|
||||
></ha-code-editor>
|
||||
</div>
|
||||
`}
|
||||
@ -280,6 +281,10 @@ export class HuiCardEditor extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private _ignoreKeydown(ev: KeyboardEvent) {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
static get styles(): CSSResult {
|
||||
return css`
|
||||
:host {
|
||||
|
@ -27,11 +27,12 @@ import {
|
||||
calcUnusedEntities,
|
||||
computeUsedEntities,
|
||||
} from "../../common/compute-unused-entities";
|
||||
import { createCardElement } from "../../create-element/create-card-element";
|
||||
import { tryCreateCardElement } from "../../create-element/create-card-element";
|
||||
import { LovelaceCard } from "../../types";
|
||||
import { getCardStubConfig } from "../get-card-stub-config";
|
||||
import { CardPickTarget, Card } from "../types";
|
||||
import { coreCards } from "../lovelace-cards";
|
||||
import { styleMap } from "lit-html/directives/style-map";
|
||||
|
||||
interface CardElement {
|
||||
card: Card;
|
||||
@ -54,6 +55,10 @@ export class HuiCardPicker extends LitElement {
|
||||
|
||||
private _usedEntities?: string[];
|
||||
|
||||
private _width?: number;
|
||||
|
||||
private _height?: number;
|
||||
|
||||
private _filterCards = memoizeOne(
|
||||
(cardElements: CardElement[], filter?: string): CardElement[] => {
|
||||
if (filter) {
|
||||
@ -92,26 +97,33 @@ export class HuiCardPicker extends LitElement {
|
||||
no-label-float
|
||||
@value-changed=${this._handleSearchChange}
|
||||
></search-input>
|
||||
<div class="cards-container">
|
||||
${this._filterCards(this._cards, this._filter).map(
|
||||
(cardElement: CardElement) => cardElement.element
|
||||
)}
|
||||
</div>
|
||||
<div class="cards-container">
|
||||
<div
|
||||
class="card manual"
|
||||
@click=${this._cardPicked}
|
||||
.config=${{ type: "" }}
|
||||
>
|
||||
<div class="preview description">
|
||||
${this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.generic.manual_description`
|
||||
)}
|
||||
</div>
|
||||
<div class="card-header">
|
||||
${this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.generic.manual`
|
||||
)}
|
||||
<div
|
||||
style=${styleMap({
|
||||
width: `${this._width}px`,
|
||||
height: `${this._height}px`,
|
||||
})}
|
||||
>
|
||||
<div class="cards-container">
|
||||
${this._filterCards(this._cards, this._filter).map(
|
||||
(cardElement: CardElement) => cardElement.element
|
||||
)}
|
||||
</div>
|
||||
<div class="cards-container">
|
||||
<div
|
||||
class="card manual"
|
||||
@click=${this._cardPicked}
|
||||
.config=${{ type: "" }}
|
||||
>
|
||||
<div class="preview description">
|
||||
${this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.generic.manual_description`
|
||||
)}
|
||||
</div>
|
||||
<div class="card-header">
|
||||
${this.hass!.localize(
|
||||
`ui.panel.lovelace.editor.card.generic.manual`
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -153,6 +165,24 @@ export class HuiCardPicker extends LitElement {
|
||||
this._loadCards();
|
||||
}
|
||||
|
||||
protected updated(changedProps) {
|
||||
super.updated(changedProps);
|
||||
// Store the width and height so that when we search, box doesn't jump
|
||||
const div = this.shadowRoot!.querySelector("div")!;
|
||||
if (!this._width) {
|
||||
const width = div.clientWidth;
|
||||
if (width) {
|
||||
this._width = width;
|
||||
}
|
||||
}
|
||||
if (!this._height) {
|
||||
const height = div.clientHeight;
|
||||
if (height) {
|
||||
this._height = height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private _loadCards() {
|
||||
let cards: Card[] = coreCards.map((card: Card) => ({
|
||||
name: this.hass!.localize(
|
||||
@ -277,8 +307,8 @@ export class HuiCardPicker extends LitElement {
|
||||
fireEvent(this, "config-changed", { config });
|
||||
}
|
||||
|
||||
private _createCardElement(cardConfig: LovelaceCardConfig) {
|
||||
const element = createCardElement(cardConfig) as LovelaceCard;
|
||||
private _tryCreateCardElement(cardConfig: LovelaceCardConfig) {
|
||||
const element = tryCreateCardElement(cardConfig) as LovelaceCard;
|
||||
element.hass = this.hass;
|
||||
element.addEventListener(
|
||||
"ll-rebuild",
|
||||
@ -295,7 +325,12 @@ export class HuiCardPicker extends LitElement {
|
||||
cardElToReplace: LovelaceCard,
|
||||
config: LovelaceCardConfig
|
||||
): void {
|
||||
const newCardEl = this._createCardElement(config);
|
||||
let newCardEl: LovelaceCard;
|
||||
try {
|
||||
newCardEl = this._tryCreateCardElement(config);
|
||||
} catch (err) {
|
||||
return;
|
||||
}
|
||||
if (cardElToReplace.parentElement) {
|
||||
cardElToReplace.parentElement!.replaceChild(newCardEl, cardElToReplace);
|
||||
}
|
||||
@ -321,7 +356,11 @@ export class HuiCardPicker extends LitElement {
|
||||
);
|
||||
|
||||
if (showElement) {
|
||||
element = this._createCardElement(cardConfig);
|
||||
try {
|
||||
element = this._tryCreateCardElement(cardConfig);
|
||||
} catch (err) {
|
||||
element = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,8 +119,8 @@ export class HuiDialogEditCard extends LitElement {
|
||||
<ha-dialog
|
||||
open
|
||||
scrimClickAction
|
||||
escapeKeyAction
|
||||
@keyup=${this._handleKeyUp}
|
||||
@keydown=${this._ignoreKeydown}
|
||||
@closed=${this._close}
|
||||
.heading=${html`${heading}
|
||||
${this._documentationURL !== undefined
|
||||
? html`
|
||||
@ -156,6 +156,7 @@ export class HuiDialogEditCard extends LitElement {
|
||||
.value=${this._cardConfig}
|
||||
@config-changed=${this._handleConfigChanged}
|
||||
@GUImode-changed=${this._handleGUIModeChanged}
|
||||
@editor-save=${this._save}
|
||||
></hui-card-editor>
|
||||
</div>
|
||||
<div class="element-preview">
|
||||
@ -192,26 +193,33 @@ export class HuiDialogEditCard extends LitElement {
|
||||
</mwc-button>
|
||||
`
|
||||
: ""}
|
||||
<mwc-button slot="primaryAction" @click=${this._close}>
|
||||
${this.hass!.localize("ui.common.cancel")}
|
||||
</mwc-button>
|
||||
${this._cardConfig !== undefined
|
||||
? html`
|
||||
<mwc-button
|
||||
slot="primaryAction"
|
||||
?disabled=${!this._canSave || this._saving}
|
||||
@click=${this._save}
|
||||
>
|
||||
${this._saving
|
||||
? html` <paper-spinner active alt="Saving"></paper-spinner> `
|
||||
: this.hass!.localize("ui.common.save")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
<div slot="primaryAction" @click=${this._save}>
|
||||
<mwc-button @click=${this._close}>
|
||||
${this.hass!.localize("ui.common.cancel")}
|
||||
</mwc-button>
|
||||
${this._cardConfig !== undefined
|
||||
? html`
|
||||
<mwc-button
|
||||
?disabled=${!this._canSave || this._saving}
|
||||
@click=${this._save}
|
||||
>
|
||||
${this._saving
|
||||
? html`
|
||||
<paper-spinner active alt="Saving"></paper-spinner>
|
||||
`
|
||||
: this.hass!.localize("ui.common.save")}
|
||||
</mwc-button>
|
||||
`
|
||||
: ``}
|
||||
</div>
|
||||
</ha-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _ignoreKeydown(ev: KeyboardEvent) {
|
||||
ev.stopPropagation();
|
||||
}
|
||||
|
||||
static get styles(): CSSResultArray {
|
||||
return [
|
||||
haStyleDialog,
|
||||
@ -339,12 +347,6 @@ export class HuiDialogEditCard extends LitElement {
|
||||
this._guiModeAvailable = ev.detail.guiModeAvailable;
|
||||
}
|
||||
|
||||
private _handleKeyUp(ev: KeyboardEvent) {
|
||||
if (ev.keyCode === 27) {
|
||||
this._close();
|
||||
}
|
||||
}
|
||||
|
||||
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
|
||||
ev.stopPropagation();
|
||||
this._GUImode = ev.detail.guiMode;
|
||||
@ -376,6 +378,9 @@ export class HuiDialogEditCard extends LitElement {
|
||||
}
|
||||
|
||||
private async _save(): Promise<void> {
|
||||
if (!this._canSave || this._saving) {
|
||||
return;
|
||||
}
|
||||
this._saving = true;
|
||||
await this._params!.saveConfig(
|
||||
this._params!.path.length === 1
|
||||
|
@ -86,6 +86,9 @@ documentContainer.innerHTML = `<custom-style>
|
||||
/* set our slider style */
|
||||
--ha-paper-slider-pin-font-size: 15px;
|
||||
|
||||
/* markdown styles */
|
||||
--markdown-code-background-color: #f6f8fa;
|
||||
|
||||
/* rgb */
|
||||
--rgb-primary-color: 3, 169, 244;
|
||||
--rgb-accent-color: 255, 152, 0;
|
||||
|
@ -278,6 +278,11 @@
|
||||
"failed_create_area": "Failed to create area."
|
||||
}
|
||||
},
|
||||
"date-range-picker": {
|
||||
"start_date": "Start date",
|
||||
"end_date": "End date",
|
||||
"select": "Select"
|
||||
},
|
||||
"relative_time": {
|
||||
"past": "{time} ago",
|
||||
"future": "In {time}",
|
||||
@ -443,6 +448,7 @@
|
||||
"buttons": {
|
||||
"add": "Add Devices via this device",
|
||||
"remove": "Remove Device",
|
||||
"clusters": "Manage Clusters",
|
||||
"reconfigure": "Reconfigure Device",
|
||||
"zigbee_information": "Zigbee device signature"
|
||||
},
|
||||
@ -520,6 +526,11 @@
|
||||
"hint_enable": "Missing config options? Enable advanced mode on",
|
||||
"link_profile_page": "your profile page"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"missing_zha": "Missing the ZHA config panel? It was moved to the ZHA entry on the {integrations_page}.",
|
||||
"missing_zwave": "Missing the Z-Wave config panel? It was moved to the Z-Wave entry on the {integrations_page}.",
|
||||
"link_integration_page": "integrations page"
|
||||
},
|
||||
"common": {
|
||||
"editor": {
|
||||
"confirm_unsaved": "You have unsaved changes. Are you sure you want to leave?"
|
||||
@ -1501,6 +1512,20 @@
|
||||
"create": "Create"
|
||||
}
|
||||
},
|
||||
"mqtt": {
|
||||
"button": "Configure",
|
||||
"title": "MQTT",
|
||||
"description_publish": "Publish a packet",
|
||||
"topic": "topic",
|
||||
"payload": "Payload (template allowed)",
|
||||
"publish": "Publish",
|
||||
"description_listen": "Listen to a topic",
|
||||
"listening_to": "Listening to",
|
||||
"subscribe_to": "Topic to subscribe to",
|
||||
"start_listening": "Start listening",
|
||||
"stop_listening": "Stop listening",
|
||||
"message_received": "Message {id} received on {topic} at {time}:"
|
||||
},
|
||||
"zha": {
|
||||
"button": "Configure",
|
||||
"header": "Configure Zigbee Home Automation",
|
||||
@ -1689,13 +1714,21 @@
|
||||
}
|
||||
},
|
||||
"history": {
|
||||
"showing_entries": "Showing entries for",
|
||||
"period": "Period"
|
||||
"ranges": {
|
||||
"today": "Today",
|
||||
"yesterday": "Yesterday",
|
||||
"this_week": "This week",
|
||||
"last_week": "Last week"
|
||||
}
|
||||
},
|
||||
"logbook": {
|
||||
"showing_entries": "[%key:ui::panel::history::showing_entries%]",
|
||||
"period": "Period",
|
||||
"entries_not_found": "No logbook entries found."
|
||||
"entries_not_found": "No logbook entries found.",
|
||||
"ranges": {
|
||||
"today": "Today",
|
||||
"yesterday": "Yesterday",
|
||||
"this_week": "This week",
|
||||
"last_week": "Last week"
|
||||
}
|
||||
},
|
||||
"lovelace": {
|
||||
"cards": {
|
||||
@ -2294,19 +2327,6 @@
|
||||
"alert_event_type": "Event type is a mandatory field",
|
||||
"notification_event_fired": "Event {type} successful fired!"
|
||||
},
|
||||
"mqtt": {
|
||||
"title": "MQTT",
|
||||
"description_publish": "Publish a packet",
|
||||
"topic": "topic",
|
||||
"payload": "Payload (template allowed)",
|
||||
"publish": "Publish",
|
||||
"description_listen": "Listen to a topic",
|
||||
"listening_to": "Listening to",
|
||||
"subscribe_to": "Topic to subscribe to",
|
||||
"start_listening": "Start listening",
|
||||
"stop_listening": "Stop listening",
|
||||
"message_received": "Message {id} received on {topic} at {time}:"
|
||||
},
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"description": "The service dev tool allows you to call any available service in Home Assistant.",
|
||||
|
@ -302,6 +302,7 @@ interface ForecastAttribute {
|
||||
datetime: string;
|
||||
templow?: number;
|
||||
precipitation?: number;
|
||||
precipitation_probability?: number;
|
||||
humidity?: number;
|
||||
condition?: string;
|
||||
}
|
||||
|
@ -483,7 +483,7 @@
|
||||
"menu": "Menú",
|
||||
"next": "Següent",
|
||||
"no": "No",
|
||||
"overflow_menu": "Menú de desbordament",
|
||||
"overflow_menu": "Menú desbordament",
|
||||
"previous": "Anterior",
|
||||
"refresh": "Actualitza",
|
||||
"save": "Desa",
|
||||
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Afegir dispositius",
|
||||
"add": "Afegeix dispositius a través d'aquest dispositiu",
|
||||
"reconfigure": "Reconfigurar dispositiu",
|
||||
"remove": "Eliminar dispositiu",
|
||||
"zigbee_information": "Informació Zigbee"
|
||||
"zigbee_information": "Signatura Zigbee del dispositiu"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Estàs segur que vols eliminar el dispositiu?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "Desconeguda",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Àrea",
|
||||
"device_name_placeholder": "Nom donat per l'usuari",
|
||||
"device_name_placeholder": "Canvia el nom del dispositiu",
|
||||
"update_name_button": "Actualitzar Nom"
|
||||
}
|
||||
}
|
||||
@ -1375,7 +1375,7 @@
|
||||
"built_using": "Creat utilitzant",
|
||||
"caption": "Informació",
|
||||
"custom_uis": "Interfícies d'usuari personalitzades:",
|
||||
"description": "Informació sobre la instal·lació de Home Assistant",
|
||||
"description": "Informació de la instal·lació de Home Assistant",
|
||||
"developed_by": "Desenvolupat per un munt de gent fantàstica.",
|
||||
"documentation": "Documentació",
|
||||
"frontend": "frontend-ui",
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "El component Estat del Sistema no està configurat. Afegeix 'system_health:' a configuration.yaml",
|
||||
"title": "Informació"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "pàgina d'integracions",
|
||||
"missing_zha": "Trobes a faltar el panell de configuració de ZHA? S'ha traslladat a l'entrada ZHA de la {integrations_page}.",
|
||||
"missing_zwave": "Trobes a faltar el panell de configuració de Z-Wave? S'ha traslladat a l'entrada Z-Wave de la {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Afegeix integració",
|
||||
"caption": "Integracions",
|
||||
@ -1660,11 +1665,11 @@
|
||||
"core": "Actualitza ubicació i personalitzacions",
|
||||
"group": "Actualitza grups",
|
||||
"heading": "Tornant a carregar la configuració",
|
||||
"input_boolean": "Torna a carregar booleans d’entrada",
|
||||
"input_datetime": "Torna a carregar les hores de la data d'entrada",
|
||||
"input_number": "Recarregar números d'entrada",
|
||||
"input_select": "Actualitza l'entrada selecciona",
|
||||
"input_text": "Recarregar textos d'entrada",
|
||||
"input_boolean": "Actualitza entrades booleanes",
|
||||
"input_datetime": "Actualitza entrades de data i hora",
|
||||
"input_number": "Actualitza entrades numèriques",
|
||||
"input_select": "Actualitza entrades de selecció",
|
||||
"input_text": "Actualitza entrades de text",
|
||||
"introduction": "Algunes parts de Home Assistant es poden actualitzar sense necessitat reiniciar-lo. Si prems actualitza s'esborrarà la configuració YAML actual i se'n carregarà la nova.",
|
||||
"person": "Actualitza persones",
|
||||
"scene": "Actualitza escenes",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Els dispositius apareixeran aquí un cop descoberts.",
|
||||
"discovery_text": "Els dispositius descoberts apareixeran aquí. Segueix les instruccions del/s teu/s dispositiu/s i posa el dispositiu/s en mode d'emparellament.",
|
||||
"header": "Domòtica amb Zigbee - Afegir dispositius",
|
||||
"no_devices_found": "No s'han trobat dispositius, assegura't que estiguin en mode vinculació i manten-los desperts mentre estiguin intentant ser descoberts.",
|
||||
"pairing_mode": "Assegura't que els dispositiu estiguin en mode vinculació. Consulta les instruccions del dispositiu per saber com fer-ho.",
|
||||
"search_again": "Torna a cercar",
|
||||
"spinner": "S'estan cercant dispositius ZHA Zigbee..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "Afegeix dispositius",
|
||||
"description": "Afegeix dispositius a la xarxa Zigbee"
|
||||
},
|
||||
"button": "Configura",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Atributs del clúster seleccionat",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "Gestió de la xarxa",
|
||||
"introduction": "Comandes que afecten tota la xarxa"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Xarxa"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Gestió del dispositiu",
|
||||
"help_node_dropdown": "Selecciona un dispositiu per visualitzar-ne les opcions (per dispositiu).",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Sembla que encara no has creat cap zona."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Configura",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Índex",
|
||||
|
@ -1373,7 +1373,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Bygget ved hjælp af",
|
||||
"caption": "Oplysninger",
|
||||
"custom_uis": "Tilpassede brugergrænseflader:",
|
||||
"description": "Oplysninger om din Home Assistant-installation",
|
||||
"developed_by": "Udviklet af en masse fantastiske mennesker.",
|
||||
"documentation": "Dokumentation",
|
||||
"frontend": "brugerflade",
|
||||
@ -1389,6 +1391,11 @@
|
||||
"system_health_error": "System Health-komponenten er ikke indlæst. Føj 'system_health:' til 'config.yaml'",
|
||||
"title": "Info"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "integrationssiden",
|
||||
"missing_zha": "Mangler ZHA-konfigurationspanelet? Det er blevet flyttet til ZHA-posten på {integrations_page}.",
|
||||
"missing_zwave": "Mangler Z-wave-konfigurationspanelet? Det er blevet flyttet til Z-wave-posten på {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Tilføj integration",
|
||||
"caption": "Integrationer",
|
||||
@ -1461,7 +1468,9 @@
|
||||
},
|
||||
"introduction": "Her er det muligt at konfigurere dine komponenter og Home Assistant. Ikke alt er muligt at konfigurere fra brugerfladen endnu, men vi arbejder på det.",
|
||||
"logs": {
|
||||
"caption": "Logs",
|
||||
"clear": "Ryd",
|
||||
"description": "Se logs for Home Assistant",
|
||||
"details": "Logdetaljer ({level})",
|
||||
"load_full_log": "Indlæs fuld Home Assistant-log",
|
||||
"loading_log": "Indlæser fejllog...",
|
||||
@ -1656,6 +1665,11 @@
|
||||
"core": "Genindlæs lokalitet og tilpasninger",
|
||||
"group": "Genindlæs grupper",
|
||||
"heading": "Genindlæsning af YAML-konfiguration",
|
||||
"input_boolean": "Genindlæs booleske input",
|
||||
"input_datetime": "Genindlæs inputdatotider",
|
||||
"input_number": "Genindlæs inputnumre",
|
||||
"input_select": "Genindlæs inputvalg",
|
||||
"input_text": "Genindlæs inputtekster",
|
||||
"introduction": "Nogle dele af Home Assistant kan genindlæses uden en genstart. Tryk på genindlæs for at aflæse den nuværende YAML-konfiguration og indlæse den nye.",
|
||||
"person": "Genindlæs personer",
|
||||
"scene": "Genindlæs scener",
|
||||
@ -1719,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Enheder vil dukke op her, når de er fundet.",
|
||||
"discovery_text": "Fundne enheder vil dukke op her. Følg instruktionerne for din enhed(er) og sæt enhed(erne) i parringstilstand.",
|
||||
"header": "Zigbee Home Automation - Tilføj enheder",
|
||||
"no_devices_found": "Ingen enheder blev fundet. Sørg for at de er i paringtilstand, og hold dem vågne, mens opdagelsen kører.",
|
||||
"pairing_mode": "Sørg for, at dine enheder er i parringstilstand. Se enhedens vejledning i, hvordan du gør dette.",
|
||||
"search_again": "Søg igen",
|
||||
"spinner": "Søger efter ZHA Zigbee-enheder..."
|
||||
},
|
||||
@ -1728,6 +1745,7 @@
|
||||
"caption": "Tilføj enheder",
|
||||
"description": "Føj enheder til Zigbee-netværk"
|
||||
},
|
||||
"button": "Konfigurer",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Egenskaber for den valgte klynge",
|
||||
@ -1806,6 +1824,9 @@
|
||||
"header": "Netværksstyring",
|
||||
"introduction": "Kommandoer, der påvirker hele netværket"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Netværk"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Enhedshåndtering",
|
||||
"help_node_dropdown": "Vælg en enhed for at få vist enhedsspecifikke indstillinger.",
|
||||
@ -1845,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Det ser ud til, at du ikke har oprettet nogen zoner endnu."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Konfigurer",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Indeks",
|
||||
@ -1886,12 +1908,17 @@
|
||||
"add_node_secure": "Tilføj sikkert knudepunkt",
|
||||
"cancel_command": "Annuller kommando",
|
||||
"heal_network": "Helbred netværk",
|
||||
"heal_node": "Helbred node",
|
||||
"node_info": "Node information",
|
||||
"print_node": "Udskriv node",
|
||||
"refresh_entity": "Opdater entitet",
|
||||
"remove_node": "Fjern knudepunkt",
|
||||
"save_config": "Gem konfiguration",
|
||||
"soft_reset": "Blød nulstilling",
|
||||
"start_network": "Start netværk",
|
||||
"stop_network": "Stop netværk",
|
||||
"test_network": "Test netværk"
|
||||
"test_network": "Test netværk",
|
||||
"test_node": "Test node"
|
||||
},
|
||||
"values": {
|
||||
"header": "Knudepunktsværdier"
|
||||
|
@ -693,10 +693,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Geräte hinzufügen",
|
||||
"add": "Geräte über dieses Gerät hinzufügen",
|
||||
"reconfigure": "Gerät neu konfigurieren",
|
||||
"remove": "Gerät entfernen",
|
||||
"zigbee_information": "ZigBee-Informationen"
|
||||
"zigbee_information": "ZigBee-Gerätesignatur"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Möchtest du das Gerät wirklich entfernen?"
|
||||
@ -716,7 +716,7 @@
|
||||
"unknown": "Unbekannt",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Bereich",
|
||||
"device_name_placeholder": "Benutzerdefinierter Name",
|
||||
"device_name_placeholder": "Gerätename ändern",
|
||||
"update_name_button": "Aktualisierung Name"
|
||||
}
|
||||
}
|
||||
@ -1722,8 +1722,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Geräte werden hier angezeigt sobald sie erkannt worden sind.",
|
||||
"discovery_text": "Erkannte Geräte werden hier angezeigt. Befolgen Sie die Anweisungen für Ihr Gerät und versetzen Sie das Gerät in den Pairing-Modus.",
|
||||
"header": "Zigbee Home Automation - Geräte hinzufügen",
|
||||
"no_devices_found": "Es wurde keine Geräte erkannt, stelle sicher das sie sich im Pairing Modus befinden und halte sie Aktiv solange die Erkennung läuft,",
|
||||
"pairing_mode": "Stellen Sie sicher, dass sich Ihre Geräte im Pairing-Modus befinden. Überprüfen Sie dazu die Anweisungen Ihres Geräts.",
|
||||
"search_again": "Erneut suchen",
|
||||
"spinner": "Suche nach ZHA Zigbee Geräten..."
|
||||
},
|
||||
@ -1731,6 +1734,7 @@
|
||||
"caption": "Geräte hinzufügen",
|
||||
"description": "Gerät dem Zigbee-Netzwerk hinzufügen."
|
||||
},
|
||||
"button": "Konfigurieren",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attribute des ausgewählten Clusters",
|
||||
@ -1809,6 +1813,9 @@
|
||||
"header": "Netzwerkverwaltung",
|
||||
"introduction": "Befehle, die das gesamte Netzwerk betreffen"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Netzwerk"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Geräteverwaltung",
|
||||
"help_node_dropdown": "Wähle ein Gerät aus, um die Geräteoptionen anzuzeigen.",
|
||||
@ -1848,6 +1855,7 @@
|
||||
"no_zones_created_yet": "Es sieht so aus, als hättest Du noch keine Zonen erstellt."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Konfigurieren",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Index",
|
||||
@ -1905,7 +1913,8 @@
|
||||
"header": "OZW Log",
|
||||
"introduction": "Schauen Sie das Protokoll an. 0 ist das Minimum (lädt das gesamte Protokoll) und 1000 ist das Maximum. Beim Laden wird ein statisches Protokoll angezeigt und das Ende wird automatisch mit der zuletzt angegebenen Anzahl von Zeilen des Protokolls aktualisiert.",
|
||||
"last_log_lines": "Anzahl der letzten Logzeilen",
|
||||
"load": "Laden"
|
||||
"load": "Laden",
|
||||
"tail": "Ende"
|
||||
},
|
||||
"services": {
|
||||
"add_node": "Knoten hinzufügen",
|
||||
@ -2352,7 +2361,7 @@
|
||||
"entity_non_numeric": "Die Entität ist nicht-numerisch: {entity}",
|
||||
"entity_not_found": "Entität nicht verfügbar: {entity}",
|
||||
"entity_unavailable": "{entity} ist derzeit nicht verfügbar",
|
||||
"starting": "Home Assistant beginnt, vielleicht ist noch nicht alles verfügbar"
|
||||
"starting": "Home Assistant startet gerade, eventuell ist noch nicht alles verfügbar"
|
||||
}
|
||||
},
|
||||
"mailbox": {
|
||||
|
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "System Health component is not loaded. Add 'system_health:' to configuration.yaml",
|
||||
"title": "Info"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "integrations page",
|
||||
"missing_zha": "Missing the ZHA config panel? It was moved to the ZHA entry on the {integrations_page}.",
|
||||
"missing_zwave": "Missing the Z-Wave config panel? It was moved to the Z-Wave entry on the {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Add integration",
|
||||
"caption": "Integrations",
|
||||
|
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Añadir dispositivos",
|
||||
"add": "Añadir dispositivos a través de este dispositivo",
|
||||
"reconfigure": "Reconfigurar dispositivo",
|
||||
"remove": "Eliminar dispositivos",
|
||||
"zigbee_information": "Información Zigbee"
|
||||
"zigbee_information": "Firma del dispositivo Zigbee"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "¿Estás seguro de que quieres eliminar este dispositivo?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "Desconocido",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Área",
|
||||
"device_name_placeholder": "Nombre dado por el usuario",
|
||||
"device_name_placeholder": "Cambiar el nombre del dispositivo",
|
||||
"update_name_button": "Cambiar nombre"
|
||||
}
|
||||
}
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "El componente Estado del Sistema no está cargado. Añade 'system_health:' a configuration.yaml",
|
||||
"title": "Información"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "página de integraciones",
|
||||
"missing_zha": "¿Echas de menos el panel de configuración de ZHA? Se ha movido a la entrada ZHA en la {integrations_page}.",
|
||||
"missing_zwave": "¿Echas de menos el panel de configuración de Z-Wave? Se ha movido a la entrada Z-Wave en la {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Añadir integración",
|
||||
"caption": "Integraciones",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Los dispositivos aparecerán aquí una vez descubiertos.",
|
||||
"discovery_text": "Los dispositivos detectados aparecerán aquí. Ponlos en modo emparejamiento siguiendo sus instrucciones.",
|
||||
"header": "Domótica Zigbee - Añadir dispositivos",
|
||||
"no_devices_found": "No se encontraron dispositivos, asegúrate de que están en modo de emparejamiento y mantenlos despiertos mientras el descubrimiento se está ejecutando.",
|
||||
"pairing_mode": "Asegúrate de que tus dispositivos están en modo de emparejamiento. Consulta las instrucciones de tu dispositivo sobre cómo hacerlo.",
|
||||
"search_again": "Buscar de nuevo",
|
||||
"spinner": "Buscando dispositivos ZHA Zigbee...."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "Añadir dispositivos",
|
||||
"description": "Añadir dispositivos a la red Zigbee"
|
||||
},
|
||||
"button": "Configurar",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Atributos del clúster seleccionado",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "Administración de la red",
|
||||
"introduction": "Comandos que afectan a toda la red."
|
||||
},
|
||||
"network": {
|
||||
"caption": "Red"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Administración de dispositivos",
|
||||
"help_node_dropdown": "Selecciona un dispositivo para ver las opciones por dispositivo.",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Parece que aún no has creado ninguna zona."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Configurar",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Índice",
|
||||
|
@ -483,6 +483,7 @@
|
||||
"menu": "Valikko",
|
||||
"next": "Seuraava",
|
||||
"no": "Ei",
|
||||
"overflow_menu": "Ylivuotovalikko",
|
||||
"previous": "Edellinen",
|
||||
"refresh": "Päivitä",
|
||||
"save": "Tallenna",
|
||||
@ -912,6 +913,8 @@
|
||||
"introduction": "Käytä automaatioita herättääksesi kotisi eloon",
|
||||
"load_error_not_editable": "Vain automaatiot tiedostossa automations.yaml ovat muokattavissa.",
|
||||
"load_error_unknown": "Virhe ladatessa automaatiota ( {err_no} )",
|
||||
"move_down": "Siirrä alaspäin",
|
||||
"move_up": "Siirrä ylöspäin",
|
||||
"save": "Tallenna",
|
||||
"triggers": {
|
||||
"add": "Laukaisuehto",
|
||||
@ -1370,7 +1373,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Rakennettu käyttäen",
|
||||
"caption": "Tiedot",
|
||||
"custom_uis": "Mukautetut käyttöliittymät:",
|
||||
"description": "Tietoja Home Assistant -asennuksesta",
|
||||
"developed_by": "Kehittänyt joukko mahtavia ihmisiä.",
|
||||
"documentation": "Dokumentointi",
|
||||
"frontend": "frontend-ui",
|
||||
@ -1386,6 +1391,11 @@
|
||||
"system_health_error": "Järjestelmän kunto-komponenttia ei ole ladattu. Lisää 'system_health:' kohteeseen configuration.yaml",
|
||||
"title": "Tiedot"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "Integraatiot",
|
||||
"missing_zha": "Etsitkö ZHA-asetuspaneelia? Se siirrettiin kohtaan ZHA {integrations_page}.",
|
||||
"missing_zwave": "Etsitkö Z-Wave-asetuspaneelia? Se siirrettiin Z-Wave-kohtaan {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Lisää integraatio",
|
||||
"caption": "Integraatiot",
|
||||
@ -1458,7 +1468,9 @@
|
||||
},
|
||||
"introduction": "Täällä voit säätää Home Assistanttia ja sen komponentteja. Huomioithan, ettei kaikkea voi vielä säätää käyttöliittymän kautta, mutta teemme jatkuvasti töitä sen mahdollistamiseksi.",
|
||||
"logs": {
|
||||
"caption": "Lokit",
|
||||
"clear": "Tyhjennä",
|
||||
"description": "Tarkastele Home Assistant -lokeja",
|
||||
"details": "Lokitiedot ( {level} )",
|
||||
"load_full_log": "Lataa Home Assistantin koko loki",
|
||||
"loading_log": "Ladataan virhelokia...",
|
||||
@ -1653,6 +1665,11 @@
|
||||
"core": "Lataa ydin uudelleen",
|
||||
"group": "Lataa ryhmät uudelleen",
|
||||
"heading": "Asetusten uudelleenlataus",
|
||||
"input_boolean": "Lataa booleanit uudelleen",
|
||||
"input_datetime": "Lataa syöttöpäivämäärät uudelleen",
|
||||
"input_number": "Lataa syöttönumerot uudelleen",
|
||||
"input_select": "Lataa valinnat uudelleen",
|
||||
"input_text": "Lataa syöttötekstit uudelleen",
|
||||
"introduction": "Jotkut Home Assistantin osat voidaan ladata uudelleen ilman, että tarvitaan uudelleenkäynnistystä. Painamalla uudelleenlatausta yaml-tiedosto luetaan uudelleen.",
|
||||
"person": "Lataa henkilöt uudelleen",
|
||||
"scene": "Lataa tilanteet uudelleen",
|
||||
@ -1716,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Laitteet tulevat tänne, kun ne löydetään.",
|
||||
"discovery_text": "Löydetyt laitteet näkyvät täällä. Noudata laitteen (laitteiden) ohjeita ja aseta laite pariliitostilaan.",
|
||||
"header": "Zigbee Home Automation - Lisää laitteita",
|
||||
"no_devices_found": "Mitään laitteita ei löydy. Varmista, että ne ovat paritustilassa ja pidä ne hereillä havaitsemisen ollessa käynnissä.",
|
||||
"pairing_mode": "Varmista, että laitteesi ovat paritustilassa. Tarkista laitteen ohjeet, kuinka tämä tehdään.",
|
||||
"search_again": "Etsi uudestaan",
|
||||
"spinner": "Etsitään ZHA Zigbee laitteita..."
|
||||
},
|
||||
@ -1725,6 +1745,7 @@
|
||||
"caption": "Lisää laitteita",
|
||||
"description": "Lisää laitteita Zigbee-verkkoon"
|
||||
},
|
||||
"button": "Määritä",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Valitun klusterin määritteet",
|
||||
@ -1803,6 +1824,9 @@
|
||||
"header": "Verkon hallinta",
|
||||
"introduction": "Koko verkkoon vaikuttavat komennot"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Verkko"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Laitehallinta",
|
||||
"help_node_dropdown": "Valitse laite tarkastellaksesi laitekohtaisia vaihtoehtoja.",
|
||||
@ -1842,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Näyttää siltä, että et ole vielä luonut vyöhykkeitä."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Määritä",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Indeksi",
|
||||
|
@ -308,12 +308,12 @@
|
||||
"lightning-rainy": "Orage / Pluie",
|
||||
"partlycloudy": "Partiellement nuageux",
|
||||
"pouring": "Averses",
|
||||
"rainy": "Pluie",
|
||||
"snowy": "Neige",
|
||||
"snowy-rainy": "Neige / Pluie",
|
||||
"sunny": "Soleil",
|
||||
"windy": "Vent",
|
||||
"windy-variant": "Vent"
|
||||
"rainy": "Pluvieux",
|
||||
"snowy": "Neigeux",
|
||||
"snowy-rainy": "Neigeux, pluvieux",
|
||||
"sunny": "Ensoleillé",
|
||||
"windy": "Venteux",
|
||||
"windy-variant": "Venteux"
|
||||
},
|
||||
"zwave": {
|
||||
"default": {
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "Le composant System Health n'est pas chargé. Ajouter 'system_health:' à configuration.yaml",
|
||||
"title": "Info"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "page d'intégration",
|
||||
"missing_zha": "Il manque le panneau de configuration de ZHA ? Il a été déplacé vers l'entrée ZHA sur la {integrations_page}.",
|
||||
"missing_zwave": "Il manque le panneau de configuration Z-Wave ? Il a été déplacé vers l'entrée Z-Wave sur la {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Ajouter l'intégration",
|
||||
"caption": "Intégrations",
|
||||
@ -1657,7 +1662,7 @@
|
||||
"section": {
|
||||
"reloading": {
|
||||
"automation": "Recharger les automatisations",
|
||||
"core": "Recharger l'emplacement et les personnalisations",
|
||||
"core": "Recharger les emplacements et personnalisations",
|
||||
"group": "Recharger les groupes",
|
||||
"heading": "Rechargement de la configuration",
|
||||
"input_boolean": "Recharger les booléens d'entrée",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Les appareils s'afficheront ici une fois découverts.",
|
||||
"discovery_text": "Les appareils découverts apparaîtront ici. Suivez les instructions pour votre / vos appareil(s) et placez-le(s) en mode de couplage.",
|
||||
"header": "Zigbee Home Automation - Ajout de périphériques",
|
||||
"no_devices_found": "Aucun appareil n'a été trouvé, assurez-vous qu'ils sont en mode d'appairage et gardez-les éveillés pendant que la découverte est en cours",
|
||||
"pairing_mode": "Assurez-vous que vos appareils sont en mode d'appairage. Consultez les instructions de votre appareil pour savoir comment procéder.",
|
||||
"search_again": "Rechercher à nouveau",
|
||||
"spinner": "Recherche de périphériques ZHA Zigbee ..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "Ajouter des appareils",
|
||||
"description": "Ajouter des appareils au réseau Zigbee"
|
||||
},
|
||||
"button": "Configurer",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attributs du cluster sélectionné",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "Gestion du réseau",
|
||||
"introduction": "Commandes qui affectent l'ensemble du réseau"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Réseau"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Gestion des appareils",
|
||||
"help_node_dropdown": "Sélectionnez un périphérique pour afficher les options par périphérique.",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Il semble que vous n'ayez pas encore créé de zones."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Configurer",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Index",
|
||||
@ -2334,7 +2347,7 @@
|
||||
"refresh": "Actualiser",
|
||||
"reload_resources": "Recharger les ressources"
|
||||
},
|
||||
"reload_lovelace": "Recharger Lovelace UI",
|
||||
"reload_lovelace": "Recharger UI",
|
||||
"reload_resources": {
|
||||
"refresh_body": "Vous devez actualiser la page pour terminer le rechargement, voulez-vous actualiser maintenant?",
|
||||
"refresh_header": "Voulez-vous vous rafraîchir ?"
|
||||
|
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Aggiungi dispositivi",
|
||||
"add": "Aggiungi dispositivi tramite questo dispositivo",
|
||||
"reconfigure": "Riconfigura dispositivo",
|
||||
"remove": "Rimuovi dispositivo",
|
||||
"zigbee_information": "Informazioni Zigbee"
|
||||
"zigbee_information": "Firma del dispositivo Zigbee"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Sei sicuro di voler rimuovere il dispositivo?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "Sconosciuto",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Area",
|
||||
"device_name_placeholder": "Nome assegnato dall'utente",
|
||||
"device_name_placeholder": "Cambia il nome del dispositivo",
|
||||
"update_name_button": "Aggiorna nome"
|
||||
}
|
||||
}
|
||||
@ -1147,7 +1147,7 @@
|
||||
"email": "E-mail",
|
||||
"email_error_msg": "E-mail non valida",
|
||||
"forgot_password": "Hai dimenticato la password?",
|
||||
"introduction": "Home Assistant Cloud fornisce una connessione remota sicura alla tua istanza quando sei lontano da casa. Consente inoltre di connettersi con i servizi cloud: Amazon Alexa e Google Assistant.",
|
||||
"introduction": "Home Assistant Cloud fornisce una connessione remota sicura alla tua istanza quando sei lontano da casa. Consente inoltre di connettersi con i servizi solo su cloud: Amazon Alexa e Google Assistant.",
|
||||
"introduction2": "Questo servizio è gestito dal nostro partner",
|
||||
"introduction2a": ", una società fondata dai fondatori di Home Assistant e Hass.io.",
|
||||
"introduction3": "Home Assistant Cloud è un servizio in abbonamento con un mese di prova gratuita. Non sono necessarie informazioni di pagamento.",
|
||||
@ -1228,7 +1228,7 @@
|
||||
"picker": {
|
||||
"entity": "Entità",
|
||||
"header": "Personalizzazioni",
|
||||
"introduction": "Modificare gli attributi per entità. Le personalizzazioni aggiunte / modificate avranno effetto immediato. Le personalizzazioni rimosse avranno effetto quando l'entità viene aggiornata."
|
||||
"introduction": "Modificare gli attributi per entità. \nLe personalizzazioni aggiunte/modificate avranno effetto immediato. \nLe personalizzazioni rimosse avranno effetto quando l'entità sarà aggiornata."
|
||||
},
|
||||
"warning": {
|
||||
"include_link": "includere customize.yaml",
|
||||
@ -1350,12 +1350,12 @@
|
||||
"caption": "Aiutanti",
|
||||
"description": "Elementi che possono aiutare a costruire le automazioni.",
|
||||
"dialog": {
|
||||
"add_helper": "Aggiungi aiuto",
|
||||
"add_helper": "Aggiungi aiutante",
|
||||
"add_platform": "Aggiungi {platform}",
|
||||
"create": "Crea"
|
||||
},
|
||||
"picker": {
|
||||
"add_helper": "Aggiungi aiuto",
|
||||
"add_helper": "Aggiungi aiutante",
|
||||
"headers": {
|
||||
"editable": "Modificabile",
|
||||
"entity_id": "ID Entità",
|
||||
@ -1382,7 +1382,7 @@
|
||||
"frontend_version": "Versione Frontend: {version} - {type}",
|
||||
"home_assistant_logo": "Logo Home Assistant",
|
||||
"icons_by": "Icone di",
|
||||
"integrations": "integrazioni",
|
||||
"integrations": "Integrazioni",
|
||||
"issues": "Problemi",
|
||||
"license": "Pubblicato sotto la licenza Apache 2.0",
|
||||
"path_configuration": "Percorso del file configuration.yaml: {path}",
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "Il componente System Health non è caricato. Aggiungere 'system_health:' a configuration.yaml",
|
||||
"title": "Informazioni"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "pagina integrazioni",
|
||||
"missing_zha": "Manca il pannello di configurazione ZHA? È stato spostato alla voce ZHA nella {integrations_page}.",
|
||||
"missing_zwave": "Manca il pannello di configurazione di Z-Wave? È stato spostato alla voce Z-Wave nella {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Aggiungi integrazione",
|
||||
"caption": "Integrazioni",
|
||||
@ -1427,7 +1432,7 @@
|
||||
"description": "Questo passaggio richiede di visitare un sito Web esterno per essere completato.",
|
||||
"open_site": "Apri sito Web"
|
||||
},
|
||||
"finish": "Finire",
|
||||
"finish": "Finito",
|
||||
"loading_first_time": "Si prega di attendere durante l'installazione dell'integrazione",
|
||||
"not_all_required_fields": "Non tutti i campi obbligatori sono compilati.",
|
||||
"submit": "Invia"
|
||||
@ -1476,27 +1481,27 @@
|
||||
"title": "Registri"
|
||||
},
|
||||
"lovelace": {
|
||||
"caption": "Cruscotti Lovelace",
|
||||
"caption": "Plance di Lovelace",
|
||||
"dashboards": {
|
||||
"cant_edit_default": "Il cruscotto standard Lovelace non può essere modificato dall'Interfaccia Utente. È possibile nasconderlo impostando un altro cruscotto come predefinito.",
|
||||
"cant_edit_yaml": "I cruscotti definiti in YAML non possono essere modificati dall'Interfaccia Utente. Modificarli in configuration.yaml.",
|
||||
"caption": "Cruscotti",
|
||||
"cant_edit_default": "La plancia standard Lovelace non può essere modificata dall'Interfaccia Utente. È possibile nasconderla impostando un'altra plancia come predefinita.",
|
||||
"cant_edit_yaml": "Le plance definite in YAML non possono essere modificate dall'Interfaccia Utente. Modificarle in configuration.yaml.",
|
||||
"caption": "Plance",
|
||||
"conf_mode": {
|
||||
"storage": "IU controllata",
|
||||
"storage": "Controllata dell'Interfaccia Utente",
|
||||
"yaml": "File YAML"
|
||||
},
|
||||
"confirm_delete": "Sei sicuro di voler eliminare questo cruscotto?",
|
||||
"default_dashboard": "Questo è il cruscotto predefinito",
|
||||
"confirm_delete": "Sei sicuro di voler eliminare questa plancia?",
|
||||
"default_dashboard": "Questa è la plancia predefinita",
|
||||
"detail": {
|
||||
"create": "Crea",
|
||||
"delete": "Elimina",
|
||||
"dismiss": "Chiudi",
|
||||
"edit_dashboard": "Modifica cruscotto",
|
||||
"edit_dashboard": "Modifica plancia",
|
||||
"icon": "Icona",
|
||||
"new_dashboard": "Aggiungi nuovo cruscotto",
|
||||
"remove_default": "Rimuovi come predefinito su questo dispositivo",
|
||||
"new_dashboard": "Aggiungi nuova plancia",
|
||||
"remove_default": "Rimuovi come predefinita su questo dispositivo",
|
||||
"require_admin": "Solo per l'amministratore",
|
||||
"set_default": "Imposta come predefinito su questo dispositivo",
|
||||
"set_default": "Imposta come predefinita su questo dispositivo",
|
||||
"show_sidebar": "Mostra nella barra laterale",
|
||||
"title": "Titolo",
|
||||
"title_required": "È richiesto il titolo.",
|
||||
@ -1505,10 +1510,10 @@
|
||||
"url_error_msg": "L'URL dovrebbe contenere un - e non può contenere spazi o caratteri speciali, ad eccezione di _ e -"
|
||||
},
|
||||
"picker": {
|
||||
"add_dashboard": "Aggiungi cruscotto",
|
||||
"add_dashboard": "Aggiungi plancia",
|
||||
"headers": {
|
||||
"conf_mode": "Metodo di configurazione",
|
||||
"default": "Predefinito",
|
||||
"default": "Predefinita",
|
||||
"filename": "Nome del file",
|
||||
"require_admin": "Solo per l'amministratore",
|
||||
"sidebar": "Mostra nella barra laterale",
|
||||
@ -1517,7 +1522,7 @@
|
||||
"open": "Aprire"
|
||||
}
|
||||
},
|
||||
"description": "Configurare i cruscotti Lovelace",
|
||||
"description": "Configura le tue plance di Lovelace",
|
||||
"resources": {
|
||||
"cant_edit_yaml": "Si utilizza Lovelace in modalità YAML, pertanto non è possibile gestire le risorse tramite l'Interfaccia Utente. Gestirli in configuration.yaml.",
|
||||
"caption": "Risorse",
|
||||
@ -1624,7 +1629,7 @@
|
||||
},
|
||||
"script": {
|
||||
"caption": "Script",
|
||||
"description": "Crea e modifica Script",
|
||||
"description": "Crea e modifica script",
|
||||
"editor": {
|
||||
"alias": "Nome",
|
||||
"default_name": "Nuovo script",
|
||||
@ -1666,10 +1671,10 @@
|
||||
"input_select": "Ricarica input a discesa",
|
||||
"input_text": "Ricarica input testuali",
|
||||
"introduction": "Alcune parti di Home Assistant possono essere ricaricate senza richiedere un riavvio. Premendo su Ricarica si rimuoverà la loro Configurazione YAML attuale e si caricherà la versione aggiornata.",
|
||||
"person": "Ricarica persone",
|
||||
"person": "Ricarica le persone",
|
||||
"scene": "Ricarica le Scene",
|
||||
"script": "Ricarica gli Script",
|
||||
"zone": "Ricarica zone"
|
||||
"zone": "Ricarica le zone"
|
||||
},
|
||||
"server_management": {
|
||||
"confirm_restart": "Sei sicuro di voler riavviare Home Assistant?",
|
||||
@ -1682,7 +1687,7 @@
|
||||
"validation": {
|
||||
"check_config": "Verifica Configurazione",
|
||||
"heading": "Convalida della configurazione",
|
||||
"introduction": "Convalidare la configurazione se di recente sono state apportate alcune modifiche alla configurazione e si desidera assicurarsi che sia tutto valido",
|
||||
"introduction": "Convalidare la configurazione se di recente sono state apportate alcune modifiche alla configurazione e ci si vuole assicurare che sia tutto valido",
|
||||
"invalid": "Configurazione non valida",
|
||||
"valid": "Configurazione valida!"
|
||||
}
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "I dispositivi verranno visualizzati qui una volta scoperti.",
|
||||
"discovery_text": "I dispositivi rilevati verranno visualizzati qui. Seguire le istruzioni per il / i dispositivo / i e posizionare il / i dispositivo / i in modalità accoppiamento.",
|
||||
"header": "Zigbee Home Automation - Aggiungi dispositivi",
|
||||
"no_devices_found": "Nessun dispositivo trovato, assicurati che siano in modalità di associazione e tienili svegli mentre la scansione è in esecuzione.",
|
||||
"pairing_mode": "Assicurati che i tuoi dispositivi siano in modalità di associazione. Controlla le istruzioni del tuo dispositivo su come eseguire questa operazione.",
|
||||
"search_again": "Cerca di nuovo",
|
||||
"spinner": "Ricerca di dispositivi ZHA Zigbee ..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "Aggiungi dispositivi",
|
||||
"description": "Aggiungi dispositivi alla rete Zigbee"
|
||||
},
|
||||
"button": "Configura",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attributi del cluster selezionato",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "Gestione della rete",
|
||||
"introduction": "Comandi che influiscono sull'intera rete"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Rete"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Gestione dei dispositivi",
|
||||
"help_node_dropdown": "Selezionare un dispositivo per visualizzare le opzioni per dispositivo.",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Sembra che tu non abbia ancora creato nessuna zona."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Configura",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Indice",
|
||||
@ -2069,7 +2082,7 @@
|
||||
}
|
||||
},
|
||||
"changed_toast": {
|
||||
"message": "La configurazione dell'Interfaccia Utente di Lovelace per questo cruscotto è stata aggiornata, ricaricare per vedere le modifiche?",
|
||||
"message": "La configurazione dell'Interfaccia Utente di Lovelace per questa plancia è stata aggiornata, ricaricare per vedere le modifiche?",
|
||||
"refresh": "Aggiorna"
|
||||
},
|
||||
"editor": {
|
||||
@ -2304,14 +2317,14 @@
|
||||
"save_config": {
|
||||
"cancel": "Rinuncia",
|
||||
"close": "Chiudi",
|
||||
"empty_config": "Iniziare con un cruscotto vuoto",
|
||||
"empty_config": "Iniziare con una plancia vuota",
|
||||
"header": "Prendi il controllo della tua interfaccia utente di Lovelace",
|
||||
"para": "Questo cruscotto è attualmente gestito da Home Assistant. E' aggiornato automaticamente quando nuove entità o componenti dell'Interfaccia Utente Lovelace diventano disponibili. Se si assume il controllo, questo cruscotto non verrà più aggiornato automaticamente. È sempre possibile creare un nuovo cruscotto in configurazione con cui esperimentare.",
|
||||
"para": "Questa plancia è attualmente gestita da Home Assistant. E' aggiornata automaticamente quando nuove entità o componenti dell'Interfaccia Utente Lovelace diventano disponibili. Se si assume il controllo, questa plancia non verrà più aggiornata automaticamente. È sempre possibile creare una nuova plancia in configurazione con cui esperimentare.",
|
||||
"para_sure": "Sei sicuro di voler prendere il controllo della tua interfaccia utente?",
|
||||
"save": "Prendere il controllo",
|
||||
"yaml_config": "Per aiutarti a iniziare qui c'è la configurazione corrente di questo cruscotto:",
|
||||
"yaml_control": "Per assumere il controllo in modalità YAML, creare un file YAML con il nome specificato nella configurazione per questo cruscotto, o il predefinito 'ui-lovelace.yaml'.",
|
||||
"yaml_mode": "Questo cruscotto sta utilizzando la modalità YAML, il che significa che non è possibile modificare la configurazione di Lovelace dall'Interfaccia Utente. Se volete gestire questo cruscotto dall'Interfaccia Utente, rimuovere 'mode: yaml' dalla configurazione di Lovelace in 'configuration.yaml'."
|
||||
"yaml_config": "Per aiutarti a iniziare qui c'è la configurazione attuale di questa plancia:",
|
||||
"yaml_control": "Per assumere il controllo in modalità YAML, creare un file YAML con il nome specificato nella tua configurazione per questa plancia, o il predefinito 'ui-lovelace.yaml'.",
|
||||
"yaml_mode": "Questa plancia sta utilizzando la modalità YAML, il che significa che non è possibile modificare la configurazione di Lovelace dall'Interfaccia Utente. Se volete gestire questa plancia dall'Interfaccia Utente, rimuovere 'mode: yaml' dalla configurazione di Lovelace in 'configuration.yaml'."
|
||||
},
|
||||
"suggest_card": {
|
||||
"add": "Aggiungi all'interfaccia utente di Lovelace",
|
||||
@ -2521,7 +2534,7 @@
|
||||
"location_name_default": "Casa"
|
||||
},
|
||||
"integration": {
|
||||
"finish": "Finire",
|
||||
"finish": "Finito",
|
||||
"intro": "Dispositivi e servizi sono rappresentati in Home Assistant come integrazioni. È possibile impostarli ora, o farlo in seguito dalla schermata di configurazione.",
|
||||
"more_integrations": "Di Più"
|
||||
},
|
||||
@ -2558,9 +2571,9 @@
|
||||
},
|
||||
"current_user": "Sei attualmente connesso come {fullName}.",
|
||||
"dashboard": {
|
||||
"description": "Scegliere un cruscotto di default per questo dispositivo.",
|
||||
"dropdown_label": "Cruscotto",
|
||||
"header": "Cruscotto"
|
||||
"description": "Scegliere una plancia di default per questo dispositivo.",
|
||||
"dropdown_label": "Plancia",
|
||||
"header": "Plancia"
|
||||
},
|
||||
"force_narrow": {
|
||||
"description": "Questo nasconderà la barra laterale per impostazione predefinita, in modo simile all'esperienza mobile",
|
||||
|
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "기기 추가",
|
||||
"add": "이 기기를 통해 기기 추가",
|
||||
"reconfigure": "기기 재설정",
|
||||
"remove": "기기 제거",
|
||||
"zigbee_information": "Zigbee 정보"
|
||||
"zigbee_information": "Zigbee 기기 서명"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "이 기기를 제거하시겠습니까?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "알 수 없슴",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "영역",
|
||||
"device_name_placeholder": "사용자 지정 이름",
|
||||
"device_name_placeholder": "기기 이름 변경",
|
||||
"update_name_button": "이름 업데이트"
|
||||
}
|
||||
}
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "시스템 상태보기 구성요소가 로드되지 않았습니다. configuration.yaml 에 'system_health:' 를 추가해주세요.",
|
||||
"title": "정보"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "통합 구성요소 페이지",
|
||||
"missing_zha": "ZHA 구성 패널이 보이지 않으신가요? {integrations_page} 의 ZHA 항목으로 이동되었습니다.",
|
||||
"missing_zwave": "Z-Wave 구성 패널이 보이지 않으신가요? {integrations_page} 의 ZHA 항목으로 이동되었습니다."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "통합 구성요소 추가",
|
||||
"caption": "통합 구성요소",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "기기가 발견되면 여기에 표시됩니다.",
|
||||
"discovery_text": "발견된 기기가 여기에 표시됩니다. 기기의 설명서를 참고하여 기기를 페어링 모드로 설정해주세요.",
|
||||
"header": "Zigbee Home Automation - 기기 추가",
|
||||
"no_devices_found": "발견된 기기가 없습니다. 기기를 검색하는 동안 기기가 페어링 모드 상태이고 절전모드가 해제되어있는지 확인해주세요.",
|
||||
"pairing_mode": "기기가 페어링 모드인지 확인해주세요. 기기의 페어링 모드 설정 방법은 기기의 설명서를 참조해주세요.",
|
||||
"search_again": "다시 검색",
|
||||
"spinner": "ZHA Zigbee 기기를 찾고있습니다..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "기기 추가",
|
||||
"description": "Zigbee 네트워크에 기기를 추가합니다"
|
||||
},
|
||||
"button": "설정",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "선택된 클러스터의 속성",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "네트워크 관리",
|
||||
"introduction": "전체 네트워크에 영향을 미치는 명령"
|
||||
},
|
||||
"network": {
|
||||
"caption": "네트워크"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "기기 관리",
|
||||
"help_node_dropdown": "기기별 옵션을 보려면 기기를 선택해주세요.",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "아직 설정한 지역이 없는 것 같습니다."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "설정",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "색인",
|
||||
|
@ -480,6 +480,7 @@
|
||||
"delete": "Läschen",
|
||||
"error_required": "Erfuerderlech",
|
||||
"loading": "Lued",
|
||||
"menu": "Menu",
|
||||
"next": "Nächst",
|
||||
"no": "Nee",
|
||||
"previous": "Virdrun",
|
||||
@ -911,6 +912,8 @@
|
||||
"introduction": "Benotzt Automatismen fir däin Haus zum Liewen ze bréngen",
|
||||
"load_error_not_editable": "Nëmmen Automatiounen am automations.yaml kënnen editéiert ginn.",
|
||||
"load_error_unknown": "Feeler beim luede vun der Automatioun ({err_no}).",
|
||||
"move_down": "No ënne réckelen",
|
||||
"move_up": "No uewe réckelen",
|
||||
"save": "Späicheren",
|
||||
"triggers": {
|
||||
"add": "Ausléiser dobäisetzen",
|
||||
@ -1369,7 +1372,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Erstallt mat",
|
||||
"caption": "Info",
|
||||
"custom_uis": "Personaliséierte Benotzer Interface:",
|
||||
"description": "Informatioune zu denger Home Assistant Installation",
|
||||
"developed_by": "Entwéckelt vun enger ganzer Rei fantastesche Leit.",
|
||||
"documentation": "Dokumentatioun",
|
||||
"frontend": "frontend-ui",
|
||||
@ -1385,6 +1390,11 @@
|
||||
"system_health_error": "System Gesondheet Komponent net gelueden. Setz 'system_health:' zur configuration.yaml dobäi",
|
||||
"title": "Info"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "Integratiouns Säit",
|
||||
"missing_zha": "Vermëss du ZHA Konfig. Tableau? Et ass op ZHA Entrée op der {integrations_page} geplënnert.",
|
||||
"missing_zwave": "Vermëss du Z-Wave Konfig. Tableau? Et ass op Z-Wave Entrée op der {integrations_page} geplënnert."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Integratioun dobäisetzen",
|
||||
"caption": "Integratiounen",
|
||||
@ -1457,7 +1467,9 @@
|
||||
},
|
||||
"introduction": "Hei ass et méiglech är Komponenten vum Home Assistant ze konfiguréieren. Net alles ass méiglech fir iwwert den Interface anzestellen, mee mir schaffen drun.",
|
||||
"logs": {
|
||||
"caption": "Logbicher",
|
||||
"clear": "Läschen",
|
||||
"description": "Home Assistant Logbicher ukucken",
|
||||
"details": "Detailler vum Log ({level})",
|
||||
"load_full_log": "Kompletten Home Assistant Log lueden",
|
||||
"loading_log": "Feeler Log gëtt gelueden...",
|
||||
@ -1715,6 +1727,7 @@
|
||||
},
|
||||
"zha": {
|
||||
"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.",
|
||||
"header": "Zigbee Home Automation - Apparater dobäisetzen",
|
||||
"search_again": "Nach emol sichen",
|
||||
@ -1724,6 +1737,7 @@
|
||||
"caption": "Apparater bäisetzen",
|
||||
"description": "Apparater am Zigbee Netzwierk bäisetzen"
|
||||
},
|
||||
"button": "Astellen",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attributer vum ausgewielten Cluster",
|
||||
@ -1802,6 +1816,9 @@
|
||||
"header": "Verwaltung vum Netzwierk",
|
||||
"introduction": "Kommandoe mat Impakt op d'gesamt Netzwierk"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Netzwierk"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Verwaltung vun den Apparaten",
|
||||
"help_node_dropdown": "Wielt een Apparat aus fir seng spezifesch Optioune ze gesinn.",
|
||||
@ -1841,6 +1858,7 @@
|
||||
"no_zones_created_yet": "Et gesäit sou aus wéi wann nach keng Zone erstallt goufen."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Astellen",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Index",
|
||||
|
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Legg til enheter",
|
||||
"add": "Legg til enheter via denne enheten",
|
||||
"reconfigure": "Rekonfigurer enhet",
|
||||
"remove": "Fjern enhet",
|
||||
"zigbee_information": "Zigbee informasjon"
|
||||
"zigbee_information": "Zigbee-enhetssignatur"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Er du sikker på at du vil fjerne enheten?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "Ukjent",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Område",
|
||||
"device_name_placeholder": "Brukers navn",
|
||||
"device_name_placeholder": "Endre enhetsnavn",
|
||||
"update_name_button": "Oppdater navn"
|
||||
}
|
||||
}
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "System tilstand komponenten er ikke lastet inn. Legg til 'system_health:' i configuration.yaml",
|
||||
"title": "Informasjon"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "integrasjonsside",
|
||||
"missing_zha": "Mangler ZHA-konfigurasjonspanelet? Den ble flyttet til ZHA-oppføringen på {integrations_page} .",
|
||||
"missing_zwave": "Mangler Z-Wave-konfigurasjonspanelet? Den ble flyttet til Z-Wave-oppføringen på {integrations_page} ."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Legg til integrasjon",
|
||||
"caption": "Integrasjoner",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Enheter vises her når de er oppdaget.",
|
||||
"discovery_text": "Oppdagede enheter vises her. Følg instruksjonene for enheten(e) og sett enheten(e) i paringsmodus.",
|
||||
"header": "Zigbee Home Automation - Legg til enheter",
|
||||
"no_devices_found": "Ingen enheter er funnet, sørg for at de er i paringsmodus og holde dem våken mens du oppdager kjører.",
|
||||
"pairing_mode": "Kontroller at enhetene er i paringsmodus. Sjekk instruksjonene til enheten om hvordan du gjør dette.",
|
||||
"search_again": "Søk på nytt",
|
||||
"spinner": "Søker etter ZHA Zigbee-enheter..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "Legg til enheter",
|
||||
"description": "Legg til enheter i Zigbee-nettverket"
|
||||
},
|
||||
"button": "Konfigurer",
|
||||
"caption": "",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attributter for den valgte klyngen",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "Nettverksadministrasjon",
|
||||
"introduction": "Kommandoer som påvirker hele nettverket"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Nettverk"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Enhetshåndtering",
|
||||
"help_node_dropdown": "Velg en enhet for å vise alternativer per enhet.",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Det ser ikke ut som du har opprettet noen soner enda"
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Konfigurer",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Indeks",
|
||||
|
@ -478,9 +478,12 @@
|
||||
"cancel": "Annuleren",
|
||||
"close": "Sluiten",
|
||||
"delete": "Verwijderen",
|
||||
"error_required": "Verplicht",
|
||||
"loading": "Bezig met laden",
|
||||
"menu": "Menu",
|
||||
"next": "Volgende",
|
||||
"no": "Nee",
|
||||
"overflow_menu": "Overloopmenu",
|
||||
"previous": "Vorige",
|
||||
"refresh": "Vernieuwen",
|
||||
"save": "Opslaan",
|
||||
@ -691,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Apparaten toevoegen",
|
||||
"add": "Apparaten toevoegen via dit apparaat",
|
||||
"reconfigure": "Apparaat opnieuw configureren",
|
||||
"remove": "Verwijder apparaat",
|
||||
"zigbee_information": "Zigbee Informatie"
|
||||
"zigbee_information": "Zigbee-apparaathandtekening"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Weet je zeker dat je het apparaat wilt verwijderen?"
|
||||
@ -714,7 +717,7 @@
|
||||
"unknown": "Onbekend",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Gebied",
|
||||
"device_name_placeholder": "Door gebruiker ingegeven naam",
|
||||
"device_name_placeholder": "Wijzig apparaatnaam",
|
||||
"update_name_button": "Naam bijwerken"
|
||||
}
|
||||
}
|
||||
@ -740,6 +743,8 @@
|
||||
"notification_toast": {
|
||||
"connection_lost": "Verbinding verbroken. Opnieuw verbinden...",
|
||||
"service_call_failed": "Kan service {service} niet aanroepen",
|
||||
"started": "Home Assistant is gestart!",
|
||||
"starting": "Home Assistant is aan het opstarten, nog niet alles is beschikbaar tot dit is voltooid.",
|
||||
"triggered": "Geactiveerd {name}"
|
||||
},
|
||||
"panel": {
|
||||
@ -908,6 +913,8 @@
|
||||
"introduction": "Gebruik automatiseringen om je huis tot leven te brengen.",
|
||||
"load_error_not_editable": "Alleen automatiseringen in automations.yaml kunnen worden bewerkt.",
|
||||
"load_error_unknown": "Fout bij laden van automatisering ({err_no}).",
|
||||
"move_down": "Verplaats omlaag",
|
||||
"move_up": "Verplaats omhoog",
|
||||
"save": "Opslaan",
|
||||
"triggers": {
|
||||
"add": "Trigger toevoegen",
|
||||
@ -1219,6 +1226,7 @@
|
||||
"different_include": "Mogelijk via een domein, een glob of een andere include.",
|
||||
"pick_attribute": "Kies een attribuut om te overschrijven",
|
||||
"picker": {
|
||||
"entity": "Entiteit",
|
||||
"header": "Aanpassingen",
|
||||
"introduction": "Pas attributen per entiteit aan. Toegevoegde/gewijzigde aanpassingen worden onmiddellijk van kracht. Verwijderde aanpassingen worden van kracht wanneer de entiteit wordt bijgewerkt."
|
||||
},
|
||||
@ -1365,7 +1373,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Gebouwd met behulp van",
|
||||
"caption": "Info",
|
||||
"custom_uis": "Aangepaste UI's:",
|
||||
"description": "Informatie over je Home Assistant installatie",
|
||||
"developed_by": "Ontwikkeld door een stel geweldige mensen.",
|
||||
"documentation": "Documentatie",
|
||||
"frontend": "Frontend",
|
||||
@ -1453,7 +1463,9 @@
|
||||
},
|
||||
"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.",
|
||||
"logs": {
|
||||
"caption": "Logboek",
|
||||
"clear": "Wis",
|
||||
"description": "Home Assistant logboek bekijken",
|
||||
"details": "Logboekdetails ({level})",
|
||||
"load_full_log": "Laad volledige Home Assistant logboek",
|
||||
"loading_log": "Foutenlogboek laden ...",
|
||||
@ -1706,10 +1718,12 @@
|
||||
"name": "Naam",
|
||||
"system": "Systeem"
|
||||
}
|
||||
}
|
||||
},
|
||||
"users_privileges_note": "Gebruikersgroepen zijn nog werk in uitvoering. De gebruiker kan de instantie niet beheren via de interface. We zijn bezig met het uitvoeren van een audit om verzekerd te zijn dat de management API-eindpunten toegang voor beheerders correct beperken."
|
||||
},
|
||||
"zha": {
|
||||
"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.",
|
||||
"header": "Zigbee Home Automation - Apparaten toevoegen",
|
||||
"search_again": "Opnieuw zoeken",
|
||||
@ -1719,6 +1733,7 @@
|
||||
"caption": "Apparaten toevoegen",
|
||||
"description": "Voeg apparaten toe aan het Zigbee netwerk"
|
||||
},
|
||||
"button": "Configureer",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attributen van het geselecteerde cluster",
|
||||
@ -1797,6 +1812,9 @@
|
||||
"header": "Netwerkbeheer",
|
||||
"introduction": "Commando's die het hele netwerk beïnvloeden"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Netwerk"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Apparaatbeheer",
|
||||
"help_node_dropdown": "Selecteer een apparaat om de opties per apparaat te bekijken.",
|
||||
@ -1836,6 +1854,7 @@
|
||||
"no_zones_created_yet": "Het lijkt erop dat je nog geen zones hebt aangemaakt."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Configureer",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Index",
|
||||
@ -1868,6 +1887,15 @@
|
||||
"set_wakeup": "Activeringsinterval instellen",
|
||||
"true": "Waar"
|
||||
},
|
||||
"node_management": {
|
||||
"add_to_group": "Toevoegen aan groep",
|
||||
"entity_info": "Entiteitsinformatie",
|
||||
"exclude_entity": "Sluit deze entiteit uit van Home Assistant",
|
||||
"group": "Groep",
|
||||
"protection": "Bescherming",
|
||||
"remove_from_group": "Verwijderen uit groep",
|
||||
"set_protection": "Bescherming instellen"
|
||||
},
|
||||
"ozw_log": {
|
||||
"header": "OZW-logboek",
|
||||
"introduction": "Bekijk het logboek. 0 is het minimum (laadt het gehele logboek) en 1000 is het maximum. Laad toont een statisch logboek en staart wordt automatisch bijgewerkt met het laatst opgegeven aantal regels van het logboek."
|
||||
@ -1877,6 +1905,7 @@
|
||||
"add_node_secure": "Secure Node toevoegen",
|
||||
"cancel_command": "Opdracht annuleren",
|
||||
"heal_network": "Herstel Netwerk",
|
||||
"refresh_entity": "Entiteit vernieuwen",
|
||||
"remove_node": "Node verwijderen",
|
||||
"save_config": "Configuratie Opslaan",
|
||||
"soft_reset": "Soft Reset",
|
||||
@ -2012,6 +2041,10 @@
|
||||
"add_item": "Item toevoegen",
|
||||
"checked_items": "Geselecteerde items",
|
||||
"clear_items": "Geselecteerde items wissen"
|
||||
},
|
||||
"starting": {
|
||||
"description": "Home Assistant is aan het opstarten, even geduld...",
|
||||
"header": "Home Assistant is aan het opstarten..."
|
||||
}
|
||||
},
|
||||
"changed_toast": {
|
||||
@ -2304,7 +2337,8 @@
|
||||
"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": "{entity} is momenteel niet beschikbaar",
|
||||
"starting": "Home Assistant is aan het opstarten, wellicht is nog niet alles beschikbaar"
|
||||
}
|
||||
},
|
||||
"mailbox": {
|
||||
|
@ -195,7 +195,7 @@
|
||||
"off": "wyłączony"
|
||||
},
|
||||
"configurator": {
|
||||
"configure": "Skonfiguruj",
|
||||
"configure": "Konfiguruj",
|
||||
"configured": "skonfigurowany"
|
||||
},
|
||||
"cover": {
|
||||
@ -480,8 +480,10 @@
|
||||
"delete": "Usuń",
|
||||
"error_required": "To pole jest wymagane",
|
||||
"loading": "Ładowanie",
|
||||
"menu": "Menu",
|
||||
"next": "Dalej",
|
||||
"no": "Nie",
|
||||
"overflow_menu": "Menu",
|
||||
"previous": "Poprzedni",
|
||||
"refresh": "Odśwież",
|
||||
"save": "Zapisz",
|
||||
@ -911,6 +913,8 @@
|
||||
"introduction": "Użyj automatyzacji, aby ożywić swój dom",
|
||||
"load_error_not_editable": "Tylko automatyzacje zdefiniowane w pliku automations.yaml są edytowalne.",
|
||||
"load_error_unknown": "Wystąpił błąd podczas ładowania automatyzacji ({err_no}).",
|
||||
"move_down": "Przesuń w dół",
|
||||
"move_up": "Przesuń w górę",
|
||||
"save": "Zapisz",
|
||||
"triggers": {
|
||||
"add": "Dodaj wyzwalacz",
|
||||
@ -1322,8 +1326,8 @@
|
||||
"introduction2": "Użyj rejestru encji, aby nadpisać jej nazwę, zmienić jej identyfikator lub usunąć ją z Home Assistant'a. Uwaga: usunięcie wpisu rejestru encji nie spowoduje usunięcia encji. Aby to zrobić, kliknij poniższy link i usuń integracje encji.",
|
||||
"remove_selected": {
|
||||
"button": "Usuń wybrane",
|
||||
"confirm_partly_text": "Można usunąć tylko {removable} z wybranych {selected} encji. Encje można usunąć tylko wtedy, gdy integracja wspiera taka możliwość. Czasami trzeba ponownie uruchomić Home Assistanta, zanim będzie można usunąć encje usuniętej integracji. Czy na pewno chcesz usunąć usuwalne encje?",
|
||||
"confirm_partly_title": "Tylko {number} wybrane encje można usunąć.",
|
||||
"confirm_partly_text": "Można usunąć tylko {removable} z wybranych {selected} encji. Encje można usunąć tylko wtedy, gdy integracja wspiera taką możliwość. Czasami trzeba ponownie uruchomić Home Assistanta, zanim będzie można usunąć encje usuniętej integracji. Czy na pewno chcesz usunąć usuwalne encje?",
|
||||
"confirm_partly_title": "Wybrane encje możliwe do usunięcia: {number}",
|
||||
"confirm_text": "Powinieneś uprzednio usunąć integrację z automatyzacji i konfiguracji Lovelace, jeśli encje w niej występują.",
|
||||
"confirm_title": "Czy chcesz usunąć encje: {number}?"
|
||||
},
|
||||
@ -1369,7 +1373,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Zbudowany przy użyciu",
|
||||
"caption": "Informacje",
|
||||
"custom_uis": "Niestandardowe interfejsy użytkownika:",
|
||||
"description": "Informacje o instalacji Home Assistanta",
|
||||
"developed_by": "Opracowany przez grono wspaniałych ludzi.",
|
||||
"documentation": "Dokumentacja",
|
||||
"frontend": "frontend-ui",
|
||||
@ -1385,6 +1391,11 @@
|
||||
"system_health_error": "Komponent kondycji systemu nie jest załadowany. Dodaj 'system_health:' do pliku configuration.yaml",
|
||||
"title": "Informacje"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "stronie integracji",
|
||||
"missing_zha": "Nie możesz znaleźć konfiguracji ZHA? Została ona przeniesiona do wpisu Z-Wave na {integrations_page}.",
|
||||
"missing_zwave": "Nie możesz znaleźć konfiguracji Z-Wave? Została ona przeniesiona do wpisu Z-Wave na {integrations_page}."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Dodaj integrację",
|
||||
"caption": "Integracje",
|
||||
@ -1457,7 +1468,9 @@
|
||||
},
|
||||
"introduction": "Tutaj możesz skonfigurować Home Assistanta i jego komponenty. Nie wszystkie opcje można konfigurować z interfejsu użytkownika, ale pracujemy nad tym.",
|
||||
"logs": {
|
||||
"caption": "Logi",
|
||||
"clear": "Wyczyść",
|
||||
"description": "Wyświetlanie logów Home Assistanta",
|
||||
"details": "Szczegóły loga ({level})",
|
||||
"load_full_log": "Załaduj cały log Home Assistanta",
|
||||
"loading_log": "Ładowanie loga błędów…",
|
||||
@ -1652,6 +1665,11 @@
|
||||
"core": "Lokalizacja i dostosowywanie",
|
||||
"group": "Grupy",
|
||||
"heading": "Ponowne wczytanie konfiguracji",
|
||||
"input_boolean": "Pomocnicy typu przełącznik",
|
||||
"input_datetime": "Pomocnicy typu data i czas",
|
||||
"input_number": "Pomocnicy typu numer",
|
||||
"input_select": "Pomocnicy typu pole wyboru",
|
||||
"input_text": "Pomocnicy typu tekst",
|
||||
"introduction": "Niektóre fragmenty konfiguracji można przeładować bez ponownego uruchamiania. Poniższe przyciski pozwalają na ponowne wczytanie konfiguracji.",
|
||||
"person": "Osoby",
|
||||
"scene": "Sceny",
|
||||
@ -1715,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Urządzenia pojawią się tutaj, jak tylko zostaną wykryte.",
|
||||
"discovery_text": "Wykryte urządzenia pojawią się tutaj. Postępuj zgodnie z instrukcjami dla urządzeń, by wprowadzić je w tryb parowania.",
|
||||
"header": "Zigbee Home Automation - dodaj urządzenia",
|
||||
"no_devices_found": "Nie znaleziono urządzeń, upewnij się, że są w trybie parowania i nie są w trybie uśpienia podczas wykrywania.",
|
||||
"pairing_mode": "Upewnij się, że urządzenie jest w trybie parowania. Zapoznaj się z instrukcją obsługi urządzenia, by dowiedzieć się, jak to zrobić.",
|
||||
"search_again": "Szukaj ponownie",
|
||||
"spinner": "Wyszukiwanie urządzeń ZHA Zigbee..."
|
||||
},
|
||||
@ -1724,6 +1745,7 @@
|
||||
"caption": "Dodaj urządzenia",
|
||||
"description": "Dodaj urządzenia do sieci Zigbee"
|
||||
},
|
||||
"button": "Konfiguruj",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Atrybuty wybranego klastra",
|
||||
@ -1802,6 +1824,9 @@
|
||||
"header": "Zarządzanie siecią",
|
||||
"introduction": "Polecenia, które wpływają na całą sieć"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Sieć"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Zarządzanie urządzeniami",
|
||||
"help_node_dropdown": "Wybierz urządzenie, aby wyświetlić jego opcje.",
|
||||
@ -1841,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Wygląda na to, że nie utworzyłeś jeszcze żadnych stref."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Konfiguruj",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Indeks",
|
||||
|
@ -767,6 +767,7 @@
|
||||
},
|
||||
"description": "Visão geral de todas as áreas da sua casa.",
|
||||
"editor": {
|
||||
"area_id": "ID da Área",
|
||||
"create": "Criar",
|
||||
"default_name": "Nova Zona",
|
||||
"delete": "Excluir",
|
||||
@ -910,6 +911,8 @@
|
||||
"introduction": "Use automações para trazer vida à sua casa",
|
||||
"load_error_not_editable": "Somente automações em automations.yaml são editáveis.",
|
||||
"load_error_unknown": "Erro ao carregar a automação ({err_no}).",
|
||||
"move_down": "Mover para baixo",
|
||||
"move_up": "Mover para cima",
|
||||
"save": "Salvar",
|
||||
"triggers": {
|
||||
"add": "Adicionar gatilho",
|
||||
@ -1368,6 +1371,7 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Construído usando",
|
||||
"caption": "Informações",
|
||||
"custom_uis": "UIs personalizadas:",
|
||||
"developed_by": "Desenvolvido por um monte de pessoas incríveis.",
|
||||
"documentation": "Documentação",
|
||||
@ -1384,6 +1388,9 @@
|
||||
"system_health_error": "O componente System Health não foi carregado. Adicione 'system_health:' ao configuration.yaml",
|
||||
"title": "Info"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "Página de integrações"
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Adicionar integração",
|
||||
"caption": "Integrações",
|
||||
@ -1456,6 +1463,7 @@
|
||||
},
|
||||
"introduction": "Aqui é possível configurar seus componentes e Home Assistant. Nem tudo é possível configurar via UI, mas estamos trabalhando nisso.",
|
||||
"logs": {
|
||||
"caption": "Logs",
|
||||
"clear": "Limpar",
|
||||
"details": "Detalhes do log ({Level})",
|
||||
"load_full_log": "Carregar todos os logs do Home Assistant",
|
||||
@ -1713,8 +1721,10 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Os dispositivos descobertos aparecerão aqui.",
|
||||
"discovery_text": "Dispositivos descobertos serão exibidos aqui. Siga as instruções para o(s) seu(s) dispositivo(s) e coloque o(s) dispositivo(s) no modo de emparelhamento.",
|
||||
"header": "Zigbee Home Automation - Adicionar dispositivos",
|
||||
"pairing_mode": "Certifique-se de que seus dispositivos estão em modo de pareamento. Verifique as instruções do seu dispositivo para saber como fazer isso.",
|
||||
"search_again": "Pesquisar novamente",
|
||||
"spinner": "Procurando por dispositivos ZHA Zigbee…"
|
||||
},
|
||||
@ -1722,6 +1732,7 @@
|
||||
"caption": "Adicionar Dispositivos",
|
||||
"description": "Adicionar dispositivos à rede Zigbee"
|
||||
},
|
||||
"button": "Configurar",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Atributos do cluster selecionado",
|
||||
@ -1800,6 +1811,9 @@
|
||||
"header": "Gerenciamento de Rede",
|
||||
"introduction": "Comandos que afetam toda a rede"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Rede"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Gerenciamento de Dispositivos",
|
||||
"help_node_dropdown": "Selecione um dispositivo para visualizar as opções por dispositivo.",
|
||||
@ -1839,6 +1853,7 @@
|
||||
"no_zones_created_yet": "Parece que você ainda não criou nenhuma zona."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Configurar",
|
||||
"caption": "",
|
||||
"common": {
|
||||
"index": "Índice",
|
||||
@ -1883,6 +1898,7 @@
|
||||
"ozw_log": {
|
||||
"header": "OZW Log",
|
||||
"introduction": "Veja o log. 0 é o mínimo (carrega o log inteiro) e 1000 é o máximo. A carga mostrará um log estático e tail será atualizada automaticamente com o último número especificado de linhas do log.",
|
||||
"last_log_lines": "Número da última linhas de log",
|
||||
"load": "Carregar"
|
||||
},
|
||||
"services": {
|
||||
@ -1890,9 +1906,12 @@
|
||||
"add_node_secure": "Adicionar Nó Seguro",
|
||||
"cancel_command": "Cancelar Comando",
|
||||
"heal_network": "Reparar rede",
|
||||
"heal_node": "Repara nó",
|
||||
"node_info": "Informações do Nó",
|
||||
"print_node": "Imprimir nó",
|
||||
"refresh_entity": "Atualizar Entidade",
|
||||
"remove_node": "Remover Nó",
|
||||
"replace_failed_node": "Substituir Nó com Falha",
|
||||
"save_config": "Salvar Configuração",
|
||||
"soft_reset": "Soft Reset",
|
||||
"start_network": "Iniciar Rede",
|
||||
|
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Добавить устройства",
|
||||
"add": "Добавить устройства через это устройство",
|
||||
"reconfigure": "Перенастроить устройство",
|
||||
"remove": "Удалить устройство",
|
||||
"zigbee_information": "Информация о Zigbee"
|
||||
"zigbee_information": "Подпись устройства Zigbee"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Вы уверены, что хотите удалить это устройство?"
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "Компонент System Health не загружен. Добавьте 'system_health:' в файл configuration.yaml.",
|
||||
"title": "О системе"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "странице интеграций",
|
||||
"missing_zha": "Отсутствует панель конфигурации ZHA? Настройки ZHA теперь находятся на {integrations_page} в карточке ZHA.",
|
||||
"missing_zwave": "Отсутствует панель конфигурации Z-Wave? Настройки Z-Wave теперь находятся на {integrations_page} в карточке Z-Wave."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Добавить интеграцию",
|
||||
"caption": "Интеграции",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Устройства появятся здесь, когда будут обнаружены.",
|
||||
"discovery_text": "Здесь будут отображаться обнаруженные устройства. Следуйте инструкциям для Вашего устройства, чтобы включить режим сопряжения.",
|
||||
"header": "Zigbee Home Automation",
|
||||
"no_devices_found": "Устройства не найдены, убедитесь, что они находятся в режиме сопряжения, и держите их активными во время обнаружения.",
|
||||
"pairing_mode": "Убедитесь, что подключаемые устройства находятся в режиме сопряжения. Чтобы узнать, как активировать режим сопряжения, ознакомьтесь с инструкциями для Вашего устройства.",
|
||||
"search_again": "Повторный поиск",
|
||||
"spinner": "Поиск Zigbee устройств..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "Добавить устройства",
|
||||
"description": "Добавить устройства в сеть Zigbee"
|
||||
},
|
||||
"button": "Настроить",
|
||||
"caption": "Zigbee Home Automation",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Атрибуты выбранного кластера",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "Управление сетью",
|
||||
"introduction": "Команды, которые влияют на всю сеть"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Сеть"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Управление устройством",
|
||||
"help_node_dropdown": "Выберите устройство для просмотра индивидуальных параметров.",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "У Вас еще нет добавленных зон."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Настроить",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Индекс",
|
||||
|
@ -480,8 +480,10 @@
|
||||
"delete": "Izbriši",
|
||||
"error_required": "Zahtevano",
|
||||
"loading": "Nalaganje",
|
||||
"menu": "Meni",
|
||||
"next": "Naslednji",
|
||||
"no": "Ne",
|
||||
"overflow_menu": "Prelivni meni",
|
||||
"previous": "Prejšnji",
|
||||
"refresh": "Osveži",
|
||||
"save": "Shrani",
|
||||
@ -692,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Dodajte naprave",
|
||||
"add": "Dodajte naprave prek te naprave",
|
||||
"reconfigure": "Ponovno konfigurirajte napravo",
|
||||
"remove": "Odstranite napravo",
|
||||
"zigbee_information": "Zigbee Informacije"
|
||||
"zigbee_information": "Podpis naprave Zigbee"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "Ali ste prepričani, da želite odstraniti napravo?"
|
||||
@ -715,7 +717,7 @@
|
||||
"unknown": "Neznano",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Območje",
|
||||
"device_name_placeholder": "Ime, ki ga je dodelil uporabnik",
|
||||
"device_name_placeholder": "Spremenite ime naprave",
|
||||
"update_name_button": "Posodobi ime"
|
||||
}
|
||||
}
|
||||
@ -911,6 +913,8 @@
|
||||
"introduction": "Uporabite avtomatizacije za oživitev vašega doma.",
|
||||
"load_error_not_editable": "Urejati je mogoče le avtomatizacije v automations.yaml.",
|
||||
"load_error_unknown": "Napaka pri nalaganju avtomatizacije ({err_no}).",
|
||||
"move_down": "Premakni navzdol",
|
||||
"move_up": "Premakni navzgor",
|
||||
"save": "Shrani",
|
||||
"triggers": {
|
||||
"add": "Dodaj sprožilec",
|
||||
@ -1369,7 +1373,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Zgrajen z uporabo",
|
||||
"caption": "Info",
|
||||
"custom_uis": "Uporabniški vmesniki po meri:",
|
||||
"description": "Informacije o vaši namestitvi programa Home Assistant",
|
||||
"developed_by": "Razvija ga kup osupljivih ljudi.",
|
||||
"documentation": "Dokumentacija",
|
||||
"frontend": "frontend-ui",
|
||||
@ -1385,6 +1391,11 @@
|
||||
"system_health_error": "Komponenta \"system health\" ni naložena. Dodajte \"system_health:\" v svoj configuration.yaml",
|
||||
"title": "Info"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "Stran za integracije",
|
||||
"missing_zha": "Ali manjka konfiguracijska plošča ZHA? Premaknjen je bil v vnos ZHA na {integrations_page} .",
|
||||
"missing_zwave": "Ali manjka konfiguracijska plošča Z-Wave? Premaknili so ga v vnos Z-Wave na {integrations_page} ."
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "Dodaj integracijo",
|
||||
"caption": "Integracije",
|
||||
@ -1457,7 +1468,9 @@
|
||||
},
|
||||
"introduction": "Tukaj je mogoče konfigurirati vaše komponente in Home Assistanta. Vsega ni mogoče konfigurirati iz uporabniškega vmesnika (vendar delamo na tem).",
|
||||
"logs": {
|
||||
"caption": "Dnevniki",
|
||||
"clear": "Počisti",
|
||||
"description": "Oglejte si Home Assistant dnevnike",
|
||||
"details": "Podrobnosti dnevnika ({level})",
|
||||
"load_full_log": "Naloži celoten dnevnik Home Assistant-a",
|
||||
"loading_log": "Nalaganje dnevnika napak ...",
|
||||
@ -1652,6 +1665,11 @@
|
||||
"core": "Ponovno naloži lokacijo in prilagoditve",
|
||||
"group": "Ponovno naloži skupine",
|
||||
"heading": "Ponovno nalaganje konfiguracije YAML",
|
||||
"input_boolean": "Ponovno naloži \"input booleans\"",
|
||||
"input_datetime": "Ponovno naloži vhodne datumske čase",
|
||||
"input_number": "Ponovno naloži vhodne številke",
|
||||
"input_select": "Ponovno naloži izbirne vnose",
|
||||
"input_text": "Ponovno naloži vhodna besedila",
|
||||
"introduction": "Nekateri deli programa Home Assistant-a se lahko naložijo brez ponovnega zagona. S ponovnim nalaganjem se trenutna konfiguracija YAML zamenja in naloži nova.",
|
||||
"person": "Ponovno naloži osebe",
|
||||
"scene": "Ponovno naloži scene",
|
||||
@ -1715,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Naprave se bodo prikazale tukaj, ko jih odkrijemo.",
|
||||
"discovery_text": "Tukaj bodo prikazane odkrite naprave. Sledite navodilom za napravo in jo postavite v način seznanjanja.",
|
||||
"header": "Zigbee Home Automation - Dodaj naprave",
|
||||
"no_devices_found": "Najdene ni bilo nobene naprave, preverite, ali so v načinu združevanje ter jih držite budne medtem, ko je v odkrivanje v teku.",
|
||||
"pairing_mode": "Prepričajte se, da so vaše naprave v načinu združevanja. Preverite navodila svoje naprave, kako to storiti.",
|
||||
"search_again": "Ponovno iskanje",
|
||||
"spinner": "Iskanje ZHA Zigbee naprav..."
|
||||
},
|
||||
@ -1724,6 +1745,7 @@
|
||||
"caption": "Dodajte naprave",
|
||||
"description": "Dodajte naprave v omrežje Zigbee"
|
||||
},
|
||||
"button": "Konfiguriraj",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Atributi izbrane gruče",
|
||||
@ -1802,6 +1824,9 @@
|
||||
"header": "Upravljanje omrežja",
|
||||
"introduction": "Ukazi, ki vplivajo na celotno omrežje"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Omrežje"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Upravljanje naprav",
|
||||
"help_node_dropdown": "Izberite napravo za ogled njenih možnosti.",
|
||||
@ -1841,6 +1866,7 @@
|
||||
"no_zones_created_yet": "Izgleda, da še niste ustvarili nobenih con."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Konfiguriraj",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Indeks",
|
||||
|
@ -694,7 +694,7 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "Lägg till enheter",
|
||||
"add": "Lägg till enheter via den här enheten",
|
||||
"reconfigure": "Konfigurera om enheten",
|
||||
"remove": "Ta bort enhet",
|
||||
"zigbee_information": "Zigbee-information"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "Okänd",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "Område",
|
||||
"device_name_placeholder": "Användarnamn",
|
||||
"device_name_placeholder": "Ändra enhetsnamn",
|
||||
"update_name_button": "Uppdatera namn"
|
||||
}
|
||||
}
|
||||
@ -744,7 +744,7 @@
|
||||
"connection_lost": "Anslutning tappad. Ansluter igen...",
|
||||
"service_call_failed": "Misslyckades med att anropa tjänsten {service}.",
|
||||
"started": "Home Assistant har startat!",
|
||||
"starting": "Home Assistant startar, allt är inte tillgängligt tills uppstarten är klar.",
|
||||
"starting": "Home Assistant startar, allt är inte tillgängligt förrän uppstarten är klar.",
|
||||
"triggered": "Utlöst {name}"
|
||||
},
|
||||
"panel": {
|
||||
@ -1013,7 +1013,7 @@
|
||||
"picker": {
|
||||
"add_automation": "Lägg till automatisering",
|
||||
"delete_automation": "Radera automation",
|
||||
"delete_confirm": "Är du säker på att du vill radera denna automatiseringen?",
|
||||
"delete_confirm": "Är du säker på att du vill radera denna automatisering?",
|
||||
"edit_automation": "Redigera automation",
|
||||
"header": "Automatiseringseditor",
|
||||
"headers": {
|
||||
@ -1373,7 +1373,9 @@
|
||||
},
|
||||
"info": {
|
||||
"built_using": "Byggt med",
|
||||
"caption": "Info",
|
||||
"custom_uis": "Anpassade användargränssnitt:",
|
||||
"description": "Info om din Home Assistant installation",
|
||||
"developed_by": "Utvecklad av ett gäng grymma människor.",
|
||||
"documentation": "Dokumentation",
|
||||
"frontend": "frontend-UI",
|
||||
@ -1461,7 +1463,9 @@
|
||||
},
|
||||
"introduction": "Här går det att konfigurera dina komponenter och Home Assistant. Det är inte möjligt att ställa in allt från användargränssnittet ännu, men vi jobbar på det.",
|
||||
"logs": {
|
||||
"caption": "Loggar",
|
||||
"clear": "Rensa",
|
||||
"description": "Visa Home Assistant loggarna",
|
||||
"details": "Logginformation ({level})",
|
||||
"load_full_log": "Ladda hela Home Assistant-loggen",
|
||||
"loading_log": "Läser in fellogg ...",
|
||||
@ -1656,7 +1660,11 @@
|
||||
"core": "Ladda om plats & anpassningar",
|
||||
"group": "Ladda om grupper",
|
||||
"heading": "YAML-konfiguration laddas om",
|
||||
"input_boolean": "Ladda om inmatning av booleska värden",
|
||||
"input_datetime": "Ladda om inmatningsdatum/tid",
|
||||
"input_number": "Ladda om inmatningsnummer",
|
||||
"input_select": "Ladda om inmatningsväljare",
|
||||
"input_text": "Ladda om inmatningstext",
|
||||
"introduction": "Vissa delar av Home Assistant kan laddas om utan att en omstart krävs. Att trycka på \"ladda om\" innebär att den nuvarande konfiguration inaktiveras och den nya laddas.",
|
||||
"person": "Ladda om personer",
|
||||
"scene": "Ladda om scenarier",
|
||||
@ -1716,12 +1724,15 @@
|
||||
"system": "System"
|
||||
}
|
||||
},
|
||||
"users_privileges_note": "Denna användaren är under konstruktion. Denna använder kommer inte kunna administrera instansen via användargränssnittet. Vi granskar fortfarande alla API-slutpunkter för att försäkra att de korrekt begränsar åtkomst till administratörer."
|
||||
"users_privileges_note": "Användar gruppen är under konstruktion. Användaren kommer inte att kunna administrera instansen via användargränssnittet. Vi granskar fortfarande alla API-slutpunkter för att försäkra att de korrekt begränsar åtkomst till endast administratörer."
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "Enheterna kommer att dyka upp här när de upptäckts.",
|
||||
"discovery_text": "Upptäckta enheter kommer dyka upp här. Följ instruktionerna för dina enheter och sätt dem i parningsläge.",
|
||||
"header": "Zigbee Home Automation - Lägg till enheter",
|
||||
"no_devices_found": "Inga enheter hittade, se till att dom är i parningsläge och håll dom aktiva medans sökning sker.",
|
||||
"pairing_mode": "Se till att dina enheter är i parningsläge. Kontrollera instruktionerna för din enhet om hur du gör det.",
|
||||
"search_again": "Sök Igen",
|
||||
"spinner": "Söker efter ZHA Zigbee-enheter ..."
|
||||
},
|
||||
@ -1729,6 +1740,7 @@
|
||||
"caption": "Lägg till enheter",
|
||||
"description": "Lägg till enheter till Zigbee-nätverket"
|
||||
},
|
||||
"button": "Konfigurera",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "Attribut för det valda klustret",
|
||||
@ -1807,6 +1819,9 @@
|
||||
"header": "Nätverkshantering",
|
||||
"introduction": "Kommandon som påverkar hela nätverket"
|
||||
},
|
||||
"network": {
|
||||
"caption": "Nätverk"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "Enhetshantering",
|
||||
"help_node_dropdown": "Välj en enhet för att visa alternativ per enhet.",
|
||||
@ -1846,6 +1861,7 @@
|
||||
"no_zones_created_yet": "Det verkar som om du inte har skapat några zoner ännu."
|
||||
},
|
||||
"zwave": {
|
||||
"button": "Konfigurera",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "Index",
|
||||
@ -1886,7 +1902,7 @@
|
||||
"group": "Grupp",
|
||||
"header": "Z-Wave nodhantering",
|
||||
"introduction": "Kör Z-Wave-kommandon som påverkar en enda nod. Välj en nod för att se en lista över tillgängliga kommandon.",
|
||||
"max_associations": "Max antal assosiationer:",
|
||||
"max_associations": "Max antal associationer:",
|
||||
"node_group_associations": "Nodgruppsassociationer",
|
||||
"node_protection": "Nodskydd",
|
||||
"node_to_control": "Nod att styra",
|
||||
@ -1911,7 +1927,7 @@
|
||||
"add_node_secure": "Lägg till nod med säkerhet",
|
||||
"cancel_command": "Avbryt kommandot",
|
||||
"heal_network": "Reparera nätverk",
|
||||
"heal_node": "Läka nod",
|
||||
"heal_node": "Läke nod",
|
||||
"node_info": "Nodinformation",
|
||||
"print_node": "Skriv ut nod",
|
||||
"refresh_entity": "Uppdatera entitet",
|
||||
@ -2351,7 +2367,7 @@
|
||||
"entity_non_numeric": "Enheten är icke-numerisk: {entity}",
|
||||
"entity_not_found": "Enheten är ej tillgänglig: {entity}",
|
||||
"entity_unavailable": "{entity} är otillgänglig",
|
||||
"starting": "Home Assistant startar, allt är kanske är tillgängligt ännu"
|
||||
"starting": "Home Assistant startar, allt är kanske inte tillgängligt ännu"
|
||||
}
|
||||
},
|
||||
"mailbox": {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -473,7 +473,7 @@
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"and": "并且",
|
||||
"and": "和",
|
||||
"back": "返回",
|
||||
"cancel": "取消",
|
||||
"close": "关闭",
|
||||
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "添加设备",
|
||||
"add": "通过此设备添加设备",
|
||||
"reconfigure": "重新配置设备",
|
||||
"remove": "删除设备",
|
||||
"zigbee_information": "Zigbee 信息"
|
||||
"zigbee_information": "Zigbee 设备签名"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "您确定要删除此设备吗?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "未知",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "区域",
|
||||
"device_name_placeholder": "用户指定的名称",
|
||||
"device_name_placeholder": "更改设备名称",
|
||||
"update_name_button": "更新名称"
|
||||
}
|
||||
}
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "未加载系统健康组件。请将 'system_health:' 添加到 configuration.yaml",
|
||||
"title": "信息"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "集成页面",
|
||||
"missing_zha": "找不到 ZHA 配置面板了吗?它已移动到{integrations_page}中的 ZHA 条目。",
|
||||
"missing_zwave": "找不到 Z-Wave 配置面板了吗?它已移动到{integrations_page}中的 Z-Wave 条目。"
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "添加集成",
|
||||
"caption": "集成",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "发现的设备会立即显示在这里。",
|
||||
"discovery_text": "发现的设备将显示在此处。按照设备的说明进行操作,并将设备置于配对模式。",
|
||||
"header": "Zigbee 家庭自动化 - 添加设备",
|
||||
"no_devices_found": "未发现设备。请确保设备处于配对模式,并且在搜索设备时保持唤醒。",
|
||||
"pairing_mode": "请确保您的设备处于配对模式。有关如何进入配对模式,请查阅设备说明书。",
|
||||
"search_again": "再次搜索",
|
||||
"spinner": "正在寻找ZHA Zigbee设备......"
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "添加设备",
|
||||
"description": "将设备添加到Zigbee网络"
|
||||
},
|
||||
"button": "配置",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "所选集群的属性",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "网络管理",
|
||||
"introduction": "影响整个网络的命令"
|
||||
},
|
||||
"network": {
|
||||
"caption": "网络"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "设备管理",
|
||||
"help_node_dropdown": "选择一个设备以查看每个设备的选项。",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "您还没有建立地点。"
|
||||
},
|
||||
"zwave": {
|
||||
"button": "配置",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "指数",
|
||||
@ -1953,8 +1966,8 @@
|
||||
"available_events": "可用事件",
|
||||
"count_listeners": " ({count} 个监听器)",
|
||||
"data": "事件数据(格式为YAML,选填)",
|
||||
"description": "将事件发送到事件总线",
|
||||
"documentation": "事件文档。",
|
||||
"description": "将事件发送到事件总线。",
|
||||
"documentation": "事件文档",
|
||||
"event_fired": "事件 {name} 已触发",
|
||||
"fire_event": "触发事件",
|
||||
"listen_to_events": "监听事件",
|
||||
|
@ -694,10 +694,10 @@
|
||||
},
|
||||
"zha_device_info": {
|
||||
"buttons": {
|
||||
"add": "新增設備",
|
||||
"add": "透過此設備新增設備",
|
||||
"reconfigure": "重新設定設備",
|
||||
"remove": "移除設備",
|
||||
"zigbee_information": "Zigbee 資訊"
|
||||
"zigbee_information": "Zigbee 設備簽章"
|
||||
},
|
||||
"confirmations": {
|
||||
"remove": "確定要移除此設備?"
|
||||
@ -717,7 +717,7 @@
|
||||
"unknown": "未知",
|
||||
"zha_device_card": {
|
||||
"area_picker_label": "分區",
|
||||
"device_name_placeholder": "設備命名",
|
||||
"device_name_placeholder": "變更設備名稱",
|
||||
"update_name_button": "更新名稱"
|
||||
}
|
||||
}
|
||||
@ -1391,6 +1391,11 @@
|
||||
"system_health_error": "系統健康元件未載入。請於 configuration.yaml 內加入「system_health:」",
|
||||
"title": "資訊"
|
||||
},
|
||||
"integration_panel_move": {
|
||||
"link_integration_page": "整合頁面",
|
||||
"missing_zha": "找不到 ZHA 設定頁面嗎?目前已經移至 {integrations_page} 中的 ZHA 物件。",
|
||||
"missing_zwave": "找不到 Z-Wave 設定頁面嗎?目前已經移至 {integrations_page} 中的 Z-Wave 物件。"
|
||||
},
|
||||
"integrations": {
|
||||
"add_integration": "新增整合",
|
||||
"caption": "整合",
|
||||
@ -1728,8 +1733,11 @@
|
||||
},
|
||||
"zha": {
|
||||
"add_device_page": {
|
||||
"discovered_text": "於探索到設備後將顯示於此處。",
|
||||
"discovery_text": "所發現的設備將會顯示於此。跟隨設備的指示並將其設定為配對模式。",
|
||||
"header": "Zigbee 家庭自動化 - 新增設備",
|
||||
"no_devices_found": "找不到設備,請確定設備處於配對模式、並於探索時保成喚醒狀態。",
|
||||
"pairing_mode": "請確定設備處於配對模式中,參閱設備的手冊以了解如何進行操作。",
|
||||
"search_again": "再次搜尋",
|
||||
"spinner": "正在搜尋 ZHA Zigbee 設備..."
|
||||
},
|
||||
@ -1737,6 +1745,7 @@
|
||||
"caption": "新增設備",
|
||||
"description": "新增設備至 Zigbee 網路"
|
||||
},
|
||||
"button": "設定",
|
||||
"caption": "ZHA",
|
||||
"cluster_attributes": {
|
||||
"attributes_of_cluster": "獲取所選叢集屬性。",
|
||||
@ -1815,6 +1824,9 @@
|
||||
"header": "網路管理",
|
||||
"introduction": "命令影響整個網路"
|
||||
},
|
||||
"network": {
|
||||
"caption": "網路"
|
||||
},
|
||||
"node_management": {
|
||||
"header": "設備管理",
|
||||
"help_node_dropdown": "選擇設備以檢視該設備選項。",
|
||||
@ -1854,6 +1866,7 @@
|
||||
"no_zones_created_yet": "看起來您還沒有新增任何區域。"
|
||||
},
|
||||
"zwave": {
|
||||
"button": "設定",
|
||||
"caption": "Z-Wave",
|
||||
"common": {
|
||||
"index": "指數",
|
||||
|
17
yarn.lock
17
yarn.lock
@ -2738,6 +2738,11 @@
|
||||
dependencies:
|
||||
"@vaadin/vaadin-development-mode-detector" "^2.0.0"
|
||||
|
||||
"@vue/web-component-wrapper@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz#bb0e46f1585a7e289b4ee6067dcc5a6ae62f1dd1"
|
||||
integrity sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw==
|
||||
|
||||
"@webassemblyjs/ast@1.8.5":
|
||||
version "1.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
|
||||
@ -11829,6 +11834,18 @@ vscode-uri@^1.0.6:
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.8.tgz#9769aaececae4026fb6e22359cb38946580ded59"
|
||||
integrity sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==
|
||||
|
||||
vue2-daterange-picker@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/vue2-daterange-picker/-/vue2-daterange-picker-0.5.1.tgz#f41f3cd20b242b7f34ce16eeea9534d9cbe9f4d7"
|
||||
integrity sha512-p0y9RyI6wqqwffKM5EYgxvNM51un/fBu9hLZ/GxXVOBqTMxjDuV8mz9iUTj4p5R80lWSBwIY7GshW5RYgS8+rw==
|
||||
dependencies:
|
||||
vue "^2.6.10"
|
||||
|
||||
vue@^2.6.10, vue@^2.6.11:
|
||||
version "2.6.11"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.11.tgz#76594d877d4b12234406e84e35275c6d514125c5"
|
||||
integrity sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==
|
||||
|
||||
watchpack@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00"
|
||||
|
Loading…
x
Reference in New Issue
Block a user