mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
Merge pull request #10930 from home-assistant/dev
This commit is contained in:
commit
b7bd7c1065
@ -132,7 +132,13 @@ class UpdateAvailableCard extends LitElement {
|
|||||||
${this._error
|
${this._error
|
||||||
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
? html`<ha-alert alert-type="error">${this._error}</ha-alert>`
|
||||||
: ""}
|
: ""}
|
||||||
${this._action === null
|
${this._version === this._version_latest
|
||||||
|
? html`<p>
|
||||||
|
${this.supervisor.localize("update_available.no_update", {
|
||||||
|
name: this._name,
|
||||||
|
})}
|
||||||
|
</p>`
|
||||||
|
: this._action === null
|
||||||
? html`
|
? html`
|
||||||
${this._changelogContent
|
${this._changelogContent
|
||||||
? html`
|
? html`
|
||||||
@ -177,7 +183,7 @@ class UpdateAvailableCard extends LitElement {
|
|||||||
)}
|
)}
|
||||||
</p>`}
|
</p>`}
|
||||||
</div>
|
</div>
|
||||||
${this._action === null
|
${this._version !== this._version_latest && this._action === null
|
||||||
? html`
|
? html`
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
${changelog
|
${changelog
|
||||||
@ -224,6 +230,9 @@ class UpdateAvailableCard extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get _shouldCreateBackup(): boolean {
|
get _shouldCreateBackup(): boolean {
|
||||||
|
if (this._updateType && !["core", "addon"].includes(this._updateType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const checkbox = this.shadowRoot?.querySelector("ha-checkbox");
|
const checkbox = this.shadowRoot?.querySelector("ha-checkbox");
|
||||||
if (checkbox) {
|
if (checkbox) {
|
||||||
return checkbox.checked;
|
return checkbox.checked;
|
||||||
|
2
setup.py
2
setup.py
@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="home-assistant-frontend",
|
name="home-assistant-frontend",
|
||||||
version="20211212.0",
|
version="20211215.0",
|
||||||
description="The Home Assistant frontend",
|
description="The Home Assistant frontend",
|
||||||
url="https://github.com/home-assistant/frontend",
|
url="https://github.com/home-assistant/frontend",
|
||||||
author="The Home Assistant Authors",
|
author="The Home Assistant Authors",
|
||||||
|
@ -208,6 +208,7 @@ export const DOMAINS_HIDE_DEFAULT_MORE_INFO = [
|
|||||||
export const DOMAINS_INPUT_ROW = [
|
export const DOMAINS_INPUT_ROW = [
|
||||||
"cover",
|
"cover",
|
||||||
"fan",
|
"fan",
|
||||||
|
"group",
|
||||||
"humidifier",
|
"humidifier",
|
||||||
"input_boolean",
|
"input_boolean",
|
||||||
"input_datetime",
|
"input_datetime",
|
||||||
|
@ -46,6 +46,7 @@ class HaAlert extends LitElement {
|
|||||||
rtl: this.rtl,
|
rtl: this.rtl,
|
||||||
[this.alertType]: true,
|
[this.alertType]: true,
|
||||||
})}"
|
})}"
|
||||||
|
role="alert"
|
||||||
>
|
>
|
||||||
<div class="icon ${this.title ? "" : "no-title"}">
|
<div class="icon ${this.title ? "" : "no-title"}">
|
||||||
<slot name="icon">
|
<slot name="icon">
|
||||||
|
@ -66,7 +66,7 @@ export class HaFormString extends LitElement implements HaFormElement {
|
|||||||
${isPassword
|
${isPassword
|
||||||
? html`<ha-icon-button
|
? html`<ha-icon-button
|
||||||
toggles
|
toggles
|
||||||
.label="Click to toggle between masked and clear password"
|
.label=${`${this._unmaskedPassword ? "Hide" : "Show"} password`}
|
||||||
@click=${this._toggleUnmaskedPassword}
|
@click=${this._toggleUnmaskedPassword}
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
.path=${this._unmaskedPassword ? mdiEyeOff : mdiEye}
|
.path=${this._unmaskedPassword ? mdiEyeOff : mdiEye}
|
||||||
|
@ -3,6 +3,7 @@ import {
|
|||||||
mdiBell,
|
mdiBell,
|
||||||
mdiCalendar,
|
mdiCalendar,
|
||||||
mdiCart,
|
mdiCart,
|
||||||
|
mdiCellphoneCog,
|
||||||
mdiChartBox,
|
mdiChartBox,
|
||||||
mdiClose,
|
mdiClose,
|
||||||
mdiCog,
|
mdiCog,
|
||||||
@ -43,7 +44,10 @@ import {
|
|||||||
PersistentNotification,
|
PersistentNotification,
|
||||||
subscribeNotifications,
|
subscribeNotifications,
|
||||||
} from "../data/persistent_notification";
|
} from "../data/persistent_notification";
|
||||||
import { getExternalConfig } from "../external_app/external_config";
|
import {
|
||||||
|
ExternalConfig,
|
||||||
|
getExternalConfig,
|
||||||
|
} from "../external_app/external_config";
|
||||||
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
|
import { actionHandler } from "../panels/lovelace/common/directives/action-handler-directive";
|
||||||
import { haStyleScrollbar } from "../resources/styles";
|
import { haStyleScrollbar } from "../resources/styles";
|
||||||
import type { HomeAssistant, PanelInfo, Route } from "../types";
|
import type { HomeAssistant, PanelInfo, Route } from "../types";
|
||||||
@ -188,6 +192,8 @@ class HaSidebar extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public editMode = false;
|
@property({ type: Boolean }) public editMode = false;
|
||||||
|
|
||||||
|
@state() private _externalConfig?: ExternalConfig;
|
||||||
|
|
||||||
@state() private _notifications?: PersistentNotification[];
|
@state() private _notifications?: PersistentNotification[];
|
||||||
|
|
||||||
@state() private _renderEmptySortable = false;
|
@state() private _renderEmptySortable = false;
|
||||||
@ -234,6 +240,7 @@ class HaSidebar extends LitElement {
|
|||||||
changedProps.has("expanded") ||
|
changedProps.has("expanded") ||
|
||||||
changedProps.has("narrow") ||
|
changedProps.has("narrow") ||
|
||||||
changedProps.has("alwaysExpand") ||
|
changedProps.has("alwaysExpand") ||
|
||||||
|
changedProps.has("_externalConfig") ||
|
||||||
changedProps.has("_notifications") ||
|
changedProps.has("_notifications") ||
|
||||||
changedProps.has("editMode") ||
|
changedProps.has("editMode") ||
|
||||||
changedProps.has("_renderEmptySortable") ||
|
changedProps.has("_renderEmptySortable") ||
|
||||||
@ -264,14 +271,15 @@ class HaSidebar extends LitElement {
|
|||||||
protected firstUpdated(changedProps: PropertyValues) {
|
protected firstUpdated(changedProps: PropertyValues) {
|
||||||
super.firstUpdated(changedProps);
|
super.firstUpdated(changedProps);
|
||||||
|
|
||||||
|
if (this.hass && this.hass.auth.external) {
|
||||||
|
getExternalConfig(this.hass.auth.external).then((conf) => {
|
||||||
|
this._externalConfig = conf;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
subscribeNotifications(this.hass.connection, (notifications) => {
|
subscribeNotifications(this.hass.connection, (notifications) => {
|
||||||
this._notifications = notifications;
|
this._notifications = notifications;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Temporary workaround for a bug in Android. Can be removed in Home Assistant 2022.2
|
|
||||||
if (this.hass.auth.external) {
|
|
||||||
getExternalConfig(this.hass.auth.external);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps) {
|
protected updated(changedProps) {
|
||||||
@ -364,6 +372,7 @@ class HaSidebar extends LitElement {
|
|||||||
: this._renderPanels(beforeSpacer)}
|
: this._renderPanels(beforeSpacer)}
|
||||||
${this._renderSpacer()}
|
${this._renderSpacer()}
|
||||||
${this._renderPanels(afterSpacer)}
|
${this._renderPanels(afterSpacer)}
|
||||||
|
${this._renderExternalConfiguration()}
|
||||||
</paper-listbox>
|
</paper-listbox>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -393,7 +402,7 @@ class HaSidebar extends LitElement {
|
|||||||
) {
|
) {
|
||||||
return html`
|
return html`
|
||||||
<a
|
<a
|
||||||
aria-role="option"
|
role="option"
|
||||||
href=${`/${urlPath}`}
|
href=${`/${urlPath}`}
|
||||||
data-panel=${urlPath}
|
data-panel=${urlPath}
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@ -498,7 +507,7 @@ class HaSidebar extends LitElement {
|
|||||||
>
|
>
|
||||||
<paper-icon-item
|
<paper-icon-item
|
||||||
class="notifications"
|
class="notifications"
|
||||||
aria-role="option"
|
role="option"
|
||||||
@click=${this._handleShowNotificationDrawer}
|
@click=${this._handleShowNotificationDrawer}
|
||||||
>
|
>
|
||||||
<ha-svg-icon slot="item-icon" .path=${mdiBell}></ha-svg-icon>
|
<ha-svg-icon slot="item-icon" .path=${mdiBell}></ha-svg-icon>
|
||||||
@ -529,7 +538,7 @@ class HaSidebar extends LitElement {
|
|||||||
href="/profile"
|
href="/profile"
|
||||||
data-panel="panel"
|
data-panel="panel"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
aria-role="option"
|
role="option"
|
||||||
aria-label=${this.hass.localize("panel.profile")}
|
aria-label=${this.hass.localize("panel.profile")}
|
||||||
@mouseenter=${this._itemMouseEnter}
|
@mouseenter=${this._itemMouseEnter}
|
||||||
@mouseleave=${this._itemMouseLeave}
|
@mouseleave=${this._itemMouseLeave}
|
||||||
@ -548,6 +557,43 @@ class HaSidebar extends LitElement {
|
|||||||
</a>`;
|
</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _renderExternalConfiguration() {
|
||||||
|
return html`${!this.hass.user?.is_admin &&
|
||||||
|
this._externalConfig &&
|
||||||
|
this._externalConfig.hasSettingsScreen
|
||||||
|
? html`
|
||||||
|
<a
|
||||||
|
role="option"
|
||||||
|
aria-label=${this.hass.localize(
|
||||||
|
"ui.sidebar.external_app_configuration"
|
||||||
|
)}
|
||||||
|
href="#external-app-configuration"
|
||||||
|
tabindex="-1"
|
||||||
|
@click=${this._handleExternalAppConfiguration}
|
||||||
|
@mouseenter=${this._itemMouseEnter}
|
||||||
|
@mouseleave=${this._itemMouseLeave}
|
||||||
|
>
|
||||||
|
<paper-icon-item>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="item-icon"
|
||||||
|
.path=${mdiCellphoneCog}
|
||||||
|
></ha-svg-icon>
|
||||||
|
<span class="item-text">
|
||||||
|
${this.hass.localize("ui.sidebar.external_app_configuration")}
|
||||||
|
</span>
|
||||||
|
</paper-icon-item>
|
||||||
|
</a>
|
||||||
|
`
|
||||||
|
: ""}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleExternalAppConfiguration(ev: Event) {
|
||||||
|
ev.preventDefault();
|
||||||
|
this.hass.auth.external!.fireMessage({
|
||||||
|
type: "config_screen/show",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private get _tooltip() {
|
private get _tooltip() {
|
||||||
return this.shadowRoot!.querySelector(".tooltip")! as HTMLDivElement;
|
return this.shadowRoot!.querySelector(".tooltip")! as HTMLDivElement;
|
||||||
}
|
}
|
||||||
|
@ -156,6 +156,7 @@ export interface MediaPlayerThumbnail {
|
|||||||
|
|
||||||
export interface ControlButton {
|
export interface ControlButton {
|
||||||
icon: string;
|
icon: string;
|
||||||
|
// Used as key for action as well as tooltip and aria-label translation key
|
||||||
action: string;
|
action: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +65,9 @@ class MoreInfoMediaPlayer extends LitElement {
|
|||||||
action=${control.action}
|
action=${control.action}
|
||||||
@click=${this._handleClick}
|
@click=${this._handleClick}
|
||||||
.path=${control.icon}
|
.path=${control.icon}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
`ui.card.media_player.${control.action}`
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
</ha-icon-button>
|
</ha-icon-button>
|
||||||
`
|
`
|
||||||
|
@ -95,8 +95,11 @@ class OnboardingCreateUser extends LitElement {
|
|||||||
private _handleValueChanged(
|
private _handleValueChanged(
|
||||||
ev: PolymerChangedEvent<HaFormDataContainer>
|
ev: PolymerChangedEvent<HaFormDataContainer>
|
||||||
): void {
|
): void {
|
||||||
|
const nameChanged = ev.detail.value.name !== this._newUser.name;
|
||||||
this._newUser = ev.detail.value;
|
this._newUser = ev.detail.value;
|
||||||
|
if (nameChanged) {
|
||||||
this._maybePopulateUsername();
|
this._maybePopulateUsername();
|
||||||
|
}
|
||||||
this._formError.password_confirm =
|
this._formError.password_confirm =
|
||||||
this._newUser.password !== this._newUser.password_confirm
|
this._newUser.password !== this._newUser.password_confirm
|
||||||
? this.localize(
|
? this.localize(
|
||||||
|
@ -17,9 +17,9 @@ import {
|
|||||||
|
|
||||||
const stateConditionStruct = object({
|
const stateConditionStruct = object({
|
||||||
condition: literal("state"),
|
condition: literal("state"),
|
||||||
entity_id: string(),
|
entity_id: optional(string()),
|
||||||
attribute: optional(string()),
|
attribute: optional(string()),
|
||||||
state: string(),
|
state: optional(string()),
|
||||||
for: optional(union([string(), forDictStruct])),
|
for: optional(union([string(), forDictStruct])),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ const stateTriggerStruct = assign(
|
|||||||
baseTriggerStruct,
|
baseTriggerStruct,
|
||||||
object({
|
object({
|
||||||
platform: literal("state"),
|
platform: literal("state"),
|
||||||
entity_id: string(),
|
entity_id: optional(string()),
|
||||||
attribute: optional(string()),
|
attribute: optional(string()),
|
||||||
from: optional(string()),
|
from: optional(string()),
|
||||||
to: optional(string()),
|
to: optional(string()),
|
||||||
|
@ -31,7 +31,7 @@ class HaConfigNavigation extends LitElement {
|
|||||||
: canShowPage(this.hass, page)
|
: canShowPage(this.hass, page)
|
||||||
)
|
)
|
||||||
? html`
|
? html`
|
||||||
<a href=${page.path} aria-role="option" tabindex="-1">
|
<a href=${page.path} role="option" tabindex="-1">
|
||||||
<paper-icon-item @click=${this._entryClicked}>
|
<paper-icon-item @click=${this._entryClicked}>
|
||||||
<div
|
<div
|
||||||
class=${page.iconColor ? "icon-background" : ""}
|
class=${page.iconColor ? "icon-background" : ""}
|
||||||
|
@ -110,7 +110,7 @@ export const configSections: { [name: string]: PageNavigation[] } = {
|
|||||||
iconColor: "#8E24AA",
|
iconColor: "#8E24AA",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/config/core",
|
path: "/config/server_control",
|
||||||
translationKey: "settings",
|
translationKey: "settings",
|
||||||
iconPath: mdiCog,
|
iconPath: mdiCog,
|
||||||
iconColor: "#4A5963",
|
iconColor: "#4A5963",
|
||||||
|
@ -95,7 +95,7 @@ class OZWConfigDashboard extends LitElement {
|
|||||||
<ha-card>
|
<ha-card>
|
||||||
<a
|
<a
|
||||||
href="/config/ozw/network/${instance.ozw_instance}"
|
href="/config/ozw/network/${instance.ozw_instance}"
|
||||||
aria-role="option"
|
role="option"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<paper-icon-item>
|
<paper-icon-item>
|
||||||
|
@ -5,6 +5,7 @@ import "@polymer/paper-input/paper-input";
|
|||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { componentsWithService } from "../../../common/config/components_with_service";
|
import { componentsWithService } from "../../../common/config/components_with_service";
|
||||||
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import "../../../components/buttons/ha-call-service-button";
|
import "../../../components/buttons/ha-call-service-button";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import { checkCoreConfig } from "../../../data/core";
|
import { checkCoreConfig } from "../../../data/core";
|
||||||
@ -157,7 +158,8 @@ export class HaConfigServerControl extends LitElement {
|
|||||||
"ui.panel.config.server_control.section.server_management.restart"
|
"ui.panel.config.server_control.section.server_management.restart"
|
||||||
)}
|
)}
|
||||||
</ha-call-service-button>
|
</ha-call-service-button>
|
||||||
<ha-call-service-button
|
${!isComponentLoaded(this.hass, "hassio")
|
||||||
|
? html`<ha-call-service-button
|
||||||
class="warning"
|
class="warning"
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
domain="homeassistant"
|
domain="homeassistant"
|
||||||
@ -168,7 +170,8 @@ export class HaConfigServerControl extends LitElement {
|
|||||||
>${this.hass.localize(
|
>${this.hass.localize(
|
||||||
"ui.panel.config.server_control.section.server_management.stop"
|
"ui.panel.config.server_control.section.server_management.stop"
|
||||||
)}
|
)}
|
||||||
</ha-call-service-button>
|
</ha-call-service-button>`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
</ha-card>
|
</ha-card>
|
||||||
|
|
||||||
|
@ -143,7 +143,12 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
<h1>
|
<h1>
|
||||||
[[localize('ui.panel.developer-tools.tabs.states.current_entities')]]
|
[[localize('ui.panel.developer-tools.tabs.states.current_entities')]]
|
||||||
</h1>
|
</h1>
|
||||||
<ha-expansion-panel header="Set state">
|
<ha-expansion-panel
|
||||||
|
header="Set state"
|
||||||
|
outlined
|
||||||
|
expanded="[[_expanded]]"
|
||||||
|
on-expanded-changed="expandedChanged"
|
||||||
|
>
|
||||||
<p>
|
<p>
|
||||||
[[localize('ui.panel.developer-tools.tabs.states.description1')]]<br />
|
[[localize('ui.panel.developer-tools.tabs.states.description1')]]<br />
|
||||||
[[localize('ui.panel.developer-tools.tabs.states.description2')]]
|
[[localize('ui.panel.developer-tools.tabs.states.description2')]]
|
||||||
@ -353,6 +358,11 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
"computeEntities(hass, _entityFilter, _stateFilter, _attributeFilter)",
|
"computeEntities(hass, _entityFilter, _stateFilter, _attributeFilter)",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_expanded: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
|
||||||
narrow: {
|
narrow: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
reflectToAttribute: true,
|
reflectToAttribute: true,
|
||||||
@ -376,6 +386,7 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
this._entity = state;
|
this._entity = state;
|
||||||
this._state = state.state;
|
this._state = state.state;
|
||||||
this._stateAttributes = dump(state.attributes);
|
this._stateAttributes = dump(state.attributes);
|
||||||
|
this._expanded = true;
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,6 +404,11 @@ class HaPanelDevState extends EventsMixin(LocalizeMixin(PolymerElement)) {
|
|||||||
this._entity = state;
|
this._entity = state;
|
||||||
this._state = state.state;
|
this._state = state.state;
|
||||||
this._stateAttributes = dump(state.attributes);
|
this._stateAttributes = dump(state.attributes);
|
||||||
|
this._expanded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
expandedChanged(ev) {
|
||||||
|
this._expanded = ev.detail.expanded;
|
||||||
}
|
}
|
||||||
|
|
||||||
entityMoreInfo(ev) {
|
entityMoreInfo(ev) {
|
||||||
|
@ -26,7 +26,7 @@ import {
|
|||||||
rgb2hex,
|
rgb2hex,
|
||||||
rgb2lab,
|
rgb2lab,
|
||||||
} from "../../../../common/color/convert-color";
|
} from "../../../../common/color/convert-color";
|
||||||
import { labDarken } from "../../../../common/color/lab";
|
import { labBrighten, labDarken } from "../../../../common/color/lab";
|
||||||
import {
|
import {
|
||||||
EnergyData,
|
EnergyData,
|
||||||
getEnergyDataCollection,
|
getEnergyDataCollection,
|
||||||
@ -247,9 +247,14 @@ export class HuiEnergyGasGraphCard
|
|||||||
const data: ChartDataset<"bar" | "line">[] = [];
|
const data: ChartDataset<"bar" | "line">[] = [];
|
||||||
const entity = this.hass.states[source.stat_energy_from];
|
const entity = this.hass.states[source.stat_energy_from];
|
||||||
|
|
||||||
const borderColor =
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(lab2rgb(labDarken(rgb2lab(hex2rgb(gasColor)), idx)))
|
? this.hass.themes.darkMode
|
||||||
|
? labBrighten(rgb2lab(hex2rgb(gasColor)), idx)
|
||||||
|
: labDarken(rgb2lab(hex2rgb(gasColor)), idx)
|
||||||
|
: undefined;
|
||||||
|
const borderColor = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: gasColor;
|
: gasColor;
|
||||||
|
|
||||||
let prevValue: number | null = null;
|
let prevValue: number | null = null;
|
||||||
|
@ -1,9 +1,3 @@
|
|||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
|
||||||
import { customElement, property, state } from "lit/decorators";
|
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|
||||||
import memoizeOne from "memoize-one";
|
|
||||||
import { classMap } from "lit/directives/class-map";
|
|
||||||
import "../../../../components/ha-card";
|
|
||||||
import {
|
import {
|
||||||
ChartData,
|
ChartData,
|
||||||
ChartDataset,
|
ChartDataset,
|
||||||
@ -17,16 +11,26 @@ import {
|
|||||||
isToday,
|
isToday,
|
||||||
startOfToday,
|
startOfToday,
|
||||||
} from "date-fns";
|
} from "date-fns";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { LovelaceCard } from "../../types";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { EnergySolarGraphCardConfig } from "../types";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import memoizeOne from "memoize-one";
|
||||||
import {
|
import {
|
||||||
hex2rgb,
|
hex2rgb,
|
||||||
lab2rgb,
|
lab2rgb,
|
||||||
rgb2hex,
|
rgb2hex,
|
||||||
rgb2lab,
|
rgb2lab,
|
||||||
} from "../../../../common/color/convert-color";
|
} from "../../../../common/color/convert-color";
|
||||||
import { labDarken } from "../../../../common/color/lab";
|
import { labBrighten, labDarken } from "../../../../common/color/lab";
|
||||||
|
import { formatTime } from "../../../../common/datetime/format_time";
|
||||||
|
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||||
|
import {
|
||||||
|
formatNumber,
|
||||||
|
numberFormatToLocale,
|
||||||
|
} from "../../../../common/number/format_number";
|
||||||
|
import "../../../../components/chart/ha-chart-base";
|
||||||
|
import "../../../../components/ha-card";
|
||||||
import {
|
import {
|
||||||
EnergyData,
|
EnergyData,
|
||||||
EnergySolarForecasts,
|
EnergySolarForecasts,
|
||||||
@ -34,15 +38,11 @@ import {
|
|||||||
getEnergySolarForecasts,
|
getEnergySolarForecasts,
|
||||||
SolarSourceTypeEnergyPreference,
|
SolarSourceTypeEnergyPreference,
|
||||||
} from "../../../../data/energy";
|
} from "../../../../data/energy";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import "../../../../components/chart/ha-chart-base";
|
|
||||||
import {
|
|
||||||
formatNumber,
|
|
||||||
numberFormatToLocale,
|
|
||||||
} from "../../../../common/number/format_number";
|
|
||||||
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
|
||||||
import { FrontendLocaleData } from "../../../../data/translation";
|
import { FrontendLocaleData } from "../../../../data/translation";
|
||||||
import { formatTime } from "../../../../common/datetime/format_time";
|
import { SubscribeMixin } from "../../../../mixins/subscribe-mixin";
|
||||||
|
import { HomeAssistant } from "../../../../types";
|
||||||
|
import { LovelaceCard } from "../../types";
|
||||||
|
import { EnergySolarGraphCardConfig } from "../types";
|
||||||
|
|
||||||
@customElement("hui-energy-solar-graph-card")
|
@customElement("hui-energy-solar-graph-card")
|
||||||
export class HuiEnergySolarGraphCard
|
export class HuiEnergySolarGraphCard
|
||||||
@ -258,9 +258,14 @@ export class HuiEnergySolarGraphCard
|
|||||||
const data: ChartDataset<"bar" | "line">[] = [];
|
const data: ChartDataset<"bar" | "line">[] = [];
|
||||||
const entity = this.hass.states[source.stat_energy_from];
|
const entity = this.hass.states[source.stat_energy_from];
|
||||||
|
|
||||||
const borderColor =
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(lab2rgb(labDarken(rgb2lab(hex2rgb(solarColor)), idx)))
|
? this.hass.themes.darkMode
|
||||||
|
? labBrighten(rgb2lab(hex2rgb(solarColor)), idx)
|
||||||
|
: labDarken(rgb2lab(hex2rgb(solarColor)), idx)
|
||||||
|
: undefined;
|
||||||
|
const borderColor = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: solarColor;
|
: solarColor;
|
||||||
|
|
||||||
let prevValue: number | null = null;
|
let prevValue: number | null = null;
|
||||||
|
@ -17,7 +17,7 @@ import {
|
|||||||
rgb2lab,
|
rgb2lab,
|
||||||
hex2rgb,
|
hex2rgb,
|
||||||
} from "../../../../common/color/convert-color";
|
} from "../../../../common/color/convert-color";
|
||||||
import { labDarken } from "../../../../common/color/lab";
|
import { labBrighten, labDarken } from "../../../../common/color/lab";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||||
import { formatNumber } from "../../../../common/number/format_number";
|
import { formatNumber } from "../../../../common/number/format_number";
|
||||||
import "../../../../components/chart/statistics-chart";
|
import "../../../../components/chart/statistics-chart";
|
||||||
@ -170,12 +170,17 @@ export class HuiEnergySourcesTableCard
|
|||||||
this._data!.stats[source.stat_energy_from]
|
this._data!.stats[source.stat_energy_from]
|
||||||
) || 0;
|
) || 0;
|
||||||
totalSolar += energy;
|
totalSolar += energy;
|
||||||
const color =
|
|
||||||
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(
|
? this.hass.themes.darkMode
|
||||||
lab2rgb(labDarken(rgb2lab(hex2rgb(solarColor)), idx))
|
? labBrighten(rgb2lab(hex2rgb(solarColor)), idx)
|
||||||
)
|
: labDarken(rgb2lab(hex2rgb(solarColor)), idx)
|
||||||
|
: undefined;
|
||||||
|
const color = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: solarColor;
|
: solarColor;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr class="mdc-data-table__row">
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
@ -229,22 +234,26 @@ export class HuiEnergySourcesTableCard
|
|||||||
this._data!.stats[source.stat_energy_to]
|
this._data!.stats[source.stat_energy_to]
|
||||||
) || 0;
|
) || 0;
|
||||||
totalBattery += energyFrom - energyTo;
|
totalBattery += energyFrom - energyTo;
|
||||||
const fromColor =
|
|
||||||
|
const modifiedFromColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(
|
? this.hass.themes.darkMode
|
||||||
lab2rgb(
|
? labBrighten(rgb2lab(hex2rgb(batteryFromColor)), idx)
|
||||||
labDarken(rgb2lab(hex2rgb(batteryFromColor)), idx)
|
: labDarken(rgb2lab(hex2rgb(batteryFromColor)), idx)
|
||||||
)
|
: undefined;
|
||||||
)
|
const fromColor = modifiedFromColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedFromColor))
|
||||||
: batteryFromColor;
|
: batteryFromColor;
|
||||||
const toColor =
|
const modifiedToColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(
|
? this.hass.themes.darkMode
|
||||||
lab2rgb(
|
? labBrighten(rgb2lab(hex2rgb(batteryToColor)), idx)
|
||||||
labDarken(rgb2lab(hex2rgb(batteryToColor)), idx)
|
: labDarken(rgb2lab(hex2rgb(batteryToColor)), idx)
|
||||||
)
|
: undefined;
|
||||||
)
|
const toColor = modifiedToColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedToColor))
|
||||||
: batteryToColor;
|
: batteryToColor;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr class="mdc-data-table__row">
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
@ -331,14 +340,17 @@ export class HuiEnergySourcesTableCard
|
|||||||
if (cost !== null) {
|
if (cost !== null) {
|
||||||
totalGridCost += cost;
|
totalGridCost += cost;
|
||||||
}
|
}
|
||||||
const color =
|
|
||||||
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(
|
? this.hass.themes.darkMode
|
||||||
lab2rgb(
|
? labBrighten(rgb2lab(hex2rgb(consumptionColor)), idx)
|
||||||
labDarken(rgb2lab(hex2rgb(consumptionColor)), idx)
|
: labDarken(rgb2lab(hex2rgb(consumptionColor)), idx)
|
||||||
)
|
: undefined;
|
||||||
)
|
const color = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: consumptionColor;
|
: consumptionColor;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr class="mdc-data-table__row">
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
@ -391,12 +403,17 @@ export class HuiEnergySourcesTableCard
|
|||||||
if (cost !== null) {
|
if (cost !== null) {
|
||||||
totalGridCost += cost;
|
totalGridCost += cost;
|
||||||
}
|
}
|
||||||
const color =
|
|
||||||
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(
|
? this.hass.themes.darkMode
|
||||||
lab2rgb(labDarken(rgb2lab(hex2rgb(returnColor)), idx))
|
? labBrighten(rgb2lab(hex2rgb(returnColor)), idx)
|
||||||
)
|
: labDarken(rgb2lab(hex2rgb(returnColor)), idx)
|
||||||
|
: undefined;
|
||||||
|
const color = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: returnColor;
|
: returnColor;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr class="mdc-data-table__row">
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
@ -473,12 +490,17 @@ export class HuiEnergySourcesTableCard
|
|||||||
if (cost !== null) {
|
if (cost !== null) {
|
||||||
totalGasCost += cost;
|
totalGasCost += cost;
|
||||||
}
|
}
|
||||||
const color =
|
|
||||||
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(
|
? this.hass.themes.darkMode
|
||||||
lab2rgb(labDarken(rgb2lab(hex2rgb(gasColor)), idx))
|
? labBrighten(rgb2lab(hex2rgb(gasColor)), idx)
|
||||||
)
|
: labDarken(rgb2lab(hex2rgb(gasColor)), idx)
|
||||||
|
: undefined;
|
||||||
|
const color = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: gasColor;
|
: gasColor;
|
||||||
|
|
||||||
return html`<tr class="mdc-data-table__row">
|
return html`<tr class="mdc-data-table__row">
|
||||||
<td class="mdc-data-table__cell cell-bullet">
|
<td class="mdc-data-table__cell cell-bullet">
|
||||||
<div
|
<div
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { ChartData, ChartDataset, ChartOptions } from "chart.js";
|
import { ChartData, ChartDataset, ChartOptions } from "chart.js";
|
||||||
import {
|
import {
|
||||||
startOfToday,
|
addHours,
|
||||||
|
differenceInDays,
|
||||||
endOfToday,
|
endOfToday,
|
||||||
isToday,
|
isToday,
|
||||||
differenceInDays,
|
startOfToday,
|
||||||
addHours,
|
|
||||||
} from "date-fns";
|
} from "date-fns";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
@ -17,7 +17,7 @@ import {
|
|||||||
rgb2hex,
|
rgb2hex,
|
||||||
rgb2lab,
|
rgb2lab,
|
||||||
} from "../../../../common/color/convert-color";
|
} from "../../../../common/color/convert-color";
|
||||||
import { labDarken } from "../../../../common/color/lab";
|
import { labBrighten, labDarken } from "../../../../common/color/lab";
|
||||||
import { formatTime } from "../../../../common/datetime/format_time";
|
import { formatTime } from "../../../../common/datetime/format_time";
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||||
import {
|
import {
|
||||||
@ -477,9 +477,15 @@ export class HuiEnergyUsageGraphCard
|
|||||||
Object.entries(sources).forEach(([statId, source], idx) => {
|
Object.entries(sources).forEach(([statId, source], idx) => {
|
||||||
const data: ChartDataset<"bar">[] = [];
|
const data: ChartDataset<"bar">[] = [];
|
||||||
const entity = this.hass.states[statId];
|
const entity = this.hass.states[statId];
|
||||||
const borderColor =
|
|
||||||
|
const modifiedColor =
|
||||||
idx > 0
|
idx > 0
|
||||||
? rgb2hex(lab2rgb(labDarken(rgb2lab(hex2rgb(colors[type])), idx)))
|
? this.hass.themes.darkMode
|
||||||
|
? labBrighten(rgb2lab(hex2rgb(colors[type])), idx)
|
||||||
|
: labDarken(rgb2lab(hex2rgb(colors[type])), idx)
|
||||||
|
: undefined;
|
||||||
|
const borderColor = modifiedColor
|
||||||
|
? rgb2hex(lab2rgb(modifiedColor))
|
||||||
: colors[type];
|
: colors[type];
|
||||||
|
|
||||||
data.push({
|
data.push({
|
||||||
|
@ -235,6 +235,9 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
|
|||||||
<div>
|
<div>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiDotsVertical}
|
.path=${mdiDotsVertical}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.cards.show_more_info"
|
||||||
|
)}
|
||||||
class="more-info"
|
class="more-info"
|
||||||
@click=${this._handleMoreInfo}
|
@click=${this._handleMoreInfo}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
|
@ -30,6 +30,7 @@ import "../../../components/ha-slider";
|
|||||||
import { UNAVAILABLE, UNAVAILABLE_STATES, UNKNOWN } from "../../../data/entity";
|
import { UNAVAILABLE, UNAVAILABLE_STATES, UNKNOWN } from "../../../data/entity";
|
||||||
import {
|
import {
|
||||||
computeMediaDescription,
|
computeMediaDescription,
|
||||||
|
ControlButton,
|
||||||
MediaPlayerEntity,
|
MediaPlayerEntity,
|
||||||
SUPPORT_NEXT_TRACK,
|
SUPPORT_NEXT_TRACK,
|
||||||
SUPPORT_PAUSE,
|
SUPPORT_PAUSE,
|
||||||
@ -108,6 +109,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const entityState = stateObj.state;
|
const entityState = stateObj.state;
|
||||||
|
const controlButton = this._computeControlButton(stateObj);
|
||||||
|
|
||||||
const buttons = html`
|
const buttons = html`
|
||||||
${!this._narrow &&
|
${!this._narrow &&
|
||||||
@ -116,6 +118,9 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiSkipPrevious}
|
.path=${mdiSkipPrevious}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.card.media_player.media_previous_track"
|
||||||
|
)}
|
||||||
@click=${this._previousTrack}
|
@click=${this._previousTrack}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -130,7 +135,10 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
supportsFeature(stateObj, SUPPORT_PAUSE)))
|
supportsFeature(stateObj, SUPPORT_PAUSE)))
|
||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${this._computeControlIcon(stateObj)}
|
.path=${controlButton.icon}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
`ui.card.media_player.${controlButton.action}`
|
||||||
|
)}
|
||||||
@click=${this._playPauseStop}
|
@click=${this._playPauseStop}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -140,6 +148,9 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiSkipNext}
|
.path=${mdiSkipNext}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.card.media_player.media_next_track"
|
||||||
|
)}
|
||||||
@click=${this._nextTrack}
|
@click=${this._nextTrack}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -162,6 +173,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiPower}
|
.path=${mdiPower}
|
||||||
|
.label=${this.hass.localize("ui.card.media_player.turn_on")}
|
||||||
@click=${this._togglePower}
|
@click=${this._togglePower}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -175,6 +187,7 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiPower}
|
.path=${mdiPower}
|
||||||
|
.label=${this.hass.localize("ui.card.media_player.turn_off")}
|
||||||
@click=${this._togglePower}
|
@click=${this._togglePower}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -193,6 +206,13 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
.path=${stateObj.attributes.is_volume_muted
|
.path=${stateObj.attributes.is_volume_muted
|
||||||
? mdiVolumeOff
|
? mdiVolumeOff
|
||||||
: mdiVolumeHigh}
|
: mdiVolumeHigh}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
`ui.card.media_player.${
|
||||||
|
stateObj.attributes.is_volume_muted
|
||||||
|
? "media_volume_mute"
|
||||||
|
: "media_volume_unmute"
|
||||||
|
}`
|
||||||
|
)}
|
||||||
@click=${this._toggleMute}
|
@click=${this._toggleMute}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -214,10 +234,16 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
? html`
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiVolumeMinus}
|
.path=${mdiVolumeMinus}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.card.media_player.media_volume_down"
|
||||||
|
)}
|
||||||
@click=${this._volumeDown}
|
@click=${this._volumeDown}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
.path=${mdiVolumePlus}
|
.path=${mdiVolumePlus}
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.card.media_player.media_volume_up"
|
||||||
|
)}
|
||||||
@click=${this._volumeUp}
|
@click=${this._volumeUp}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
`
|
`
|
||||||
@ -249,14 +275,14 @@ class HuiMediaPlayerEntityRow extends LitElement implements LovelaceRow {
|
|||||||
this._veryNarrow = (this.clientWidth || 0) < 225;
|
this._veryNarrow = (this.clientWidth || 0) < 225;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _computeControlIcon(stateObj: HassEntity): string {
|
private _computeControlButton(stateObj: HassEntity): ControlButton {
|
||||||
return stateObj.state === "on"
|
return stateObj.state === "on"
|
||||||
? mdiPlayPause
|
? { icon: mdiPlayPause, action: "media_play_pause" }
|
||||||
: stateObj.state !== "playing"
|
: stateObj.state !== "playing"
|
||||||
? mdiPlay
|
? { icon: mdiPlay, action: "media_play" }
|
||||||
: supportsFeature(stateObj, SUPPORT_PAUSE)
|
: supportsFeature(stateObj, SUPPORT_PAUSE)
|
||||||
? mdiPause
|
? { icon: mdiPause, action: "media_pause" }
|
||||||
: mdiStop;
|
: { icon: mdiStop, action: "media_stop" };
|
||||||
}
|
}
|
||||||
|
|
||||||
private _togglePower(): void {
|
private _togglePower(): void {
|
||||||
|
@ -195,8 +195,14 @@
|
|||||||
"turn_off": "Turn off",
|
"turn_off": "Turn off",
|
||||||
"media_play": "Play",
|
"media_play": "Play",
|
||||||
"media_play_pause": "Play/pause",
|
"media_play_pause": "Play/pause",
|
||||||
"media_next_track": "Next",
|
"media_pause": "Pause",
|
||||||
"media_previous_track": "Previous",
|
"media_stop": "Stop",
|
||||||
|
"media_next_track": "Next track",
|
||||||
|
"media_previous_track": "Previous track",
|
||||||
|
"media_volume_up": "Volume up",
|
||||||
|
"media_volume_down": "Volume down",
|
||||||
|
"media_volume_mute": "Volume mute",
|
||||||
|
"media_volume_unmute": "Volume unmute",
|
||||||
"text_to_speak": "Text to speak"
|
"text_to_speak": "Text to speak"
|
||||||
},
|
},
|
||||||
"persistent_notification": {
|
"persistent_notification": {
|
||||||
@ -689,7 +695,7 @@
|
|||||||
"close_cover": "Close cover",
|
"close_cover": "Close cover",
|
||||||
"open_tilt_cover": "Open cover tilt",
|
"open_tilt_cover": "Open cover tilt",
|
||||||
"close_tilt_cover": "Close cover tilt",
|
"close_tilt_cover": "Close cover tilt",
|
||||||
"stop_cover": "Stop cover from moving"
|
"stop_cover": "Stop cover"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"entity_registry": {
|
"entity_registry": {
|
||||||
@ -922,6 +928,7 @@
|
|||||||
"dismiss": "Dismiss"
|
"dismiss": "Dismiss"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
|
"external_app_configuration": "App Configuration",
|
||||||
"sidebar_toggle": "Sidebar Toggle",
|
"sidebar_toggle": "Sidebar Toggle",
|
||||||
"done": "Done",
|
"done": "Done",
|
||||||
"hide_panel": "Hide panel",
|
"hide_panel": "Hide panel",
|
||||||
@ -4269,7 +4276,8 @@
|
|||||||
"create_backup": "Create backup before updating",
|
"create_backup": "Create backup before updating",
|
||||||
"description": "You have {version} installed. Click update to update to version {newest_version}",
|
"description": "You have {version} installed. Click update to update to version {newest_version}",
|
||||||
"updating": "Updating {name} to version {version}",
|
"updating": "Updating {name} to version {version}",
|
||||||
"creating_backup": "Creating backup of {name}"
|
"creating_backup": "Creating backup of {name}",
|
||||||
|
"no_update": "No update available for {name}"
|
||||||
},
|
},
|
||||||
"confirm": {
|
"confirm": {
|
||||||
"restart": {
|
"restart": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user