mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
20230703.0 (#17150)
This commit is contained in:
commit
b309c64d7b
@ -23,6 +23,7 @@ import {
|
|||||||
SupervisorObject,
|
SupervisorObject,
|
||||||
supervisorCollection,
|
supervisorCollection,
|
||||||
SupervisorKeys,
|
SupervisorKeys,
|
||||||
|
cleanupSupervisorCollection,
|
||||||
} from "../../src/data/supervisor/supervisor";
|
} from "../../src/data/supervisor/supervisor";
|
||||||
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin";
|
||||||
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
|
import { urlSyncMixin } from "../../src/state/url-sync-mixin";
|
||||||
@ -67,6 +68,10 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
this._unsubs[unsub]();
|
this._unsubs[unsub]();
|
||||||
delete this._unsubs[unsub];
|
delete this._unsubs[unsub];
|
||||||
});
|
});
|
||||||
|
Object.keys(this._collections).forEach((collection) => {
|
||||||
|
cleanupSupervisorCollection(this.hass.connection, collection);
|
||||||
|
});
|
||||||
|
this._collections = {};
|
||||||
this.removeEventListener(
|
this.removeEventListener(
|
||||||
"supervisor-collection-refresh",
|
"supervisor-collection-refresh",
|
||||||
this._handleSupervisorStoreRefreshEvent
|
this._handleSupervisorStoreRefreshEvent
|
||||||
@ -114,7 +119,9 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
private async _handleSupervisorStoreRefreshEvent(ev) {
|
private async _handleSupervisorStoreRefreshEvent(ev) {
|
||||||
const collection = ev.detail.collection;
|
const collection = ev.detail.collection;
|
||||||
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
|
if (atLeastVersion(this.hass.config.version, 2021, 2, 4)) {
|
||||||
this._collections[collection].refresh();
|
if (collection in this._collections) {
|
||||||
|
this._collections[collection].refresh();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -129,11 +136,17 @@ export class SupervisorBaseElement extends urlSyncMixin(
|
|||||||
if (this._unsubs[collection]) {
|
if (this._unsubs[collection]) {
|
||||||
this._unsubs[collection]();
|
this._unsubs[collection]();
|
||||||
}
|
}
|
||||||
this._unsubs[collection] = this._collections[collection].subscribe((data) =>
|
try {
|
||||||
this._updateSupervisor({
|
this._unsubs[collection] = this._collections[collection].subscribe(
|
||||||
[collection]: data,
|
(data) =>
|
||||||
})
|
this._updateSupervisor({
|
||||||
);
|
[collection]: data,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _initSupervisor(): Promise<void> {
|
private async _initSupervisor(): Promise<void> {
|
||||||
|
14
package.json
14
package.json
@ -52,7 +52,7 @@
|
|||||||
"@lit-labs/context": "0.3.3",
|
"@lit-labs/context": "0.3.3",
|
||||||
"@lit-labs/motion": "1.0.3",
|
"@lit-labs/motion": "1.0.3",
|
||||||
"@lit-labs/virtualizer": "2.0.3",
|
"@lit-labs/virtualizer": "2.0.3",
|
||||||
"@lrnwebcomponents/simple-tooltip": "7.0.10",
|
"@lrnwebcomponents/simple-tooltip": "7.0.11",
|
||||||
"@material/chips": "=14.0.0-canary.53b3cad2f.0",
|
"@material/chips": "=14.0.0-canary.53b3cad2f.0",
|
||||||
"@material/data-table": "=14.0.0-canary.53b3cad2f.0",
|
"@material/data-table": "=14.0.0-canary.53b3cad2f.0",
|
||||||
"@material/mwc-button": "0.27.0",
|
"@material/mwc-button": "0.27.0",
|
||||||
@ -78,7 +78,7 @@
|
|||||||
"@material/mwc-top-app-bar": "0.27.0",
|
"@material/mwc-top-app-bar": "0.27.0",
|
||||||
"@material/mwc-top-app-bar-fixed": "0.27.0",
|
"@material/mwc-top-app-bar-fixed": "0.27.0",
|
||||||
"@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0",
|
"@material/top-app-bar": "=14.0.0-canary.53b3cad2f.0",
|
||||||
"@material/web": "=1.0.0-pre.11",
|
"@material/web": "=1.0.0-pre.12",
|
||||||
"@mdi/js": "7.2.96",
|
"@mdi/js": "7.2.96",
|
||||||
"@mdi/svg": "7.2.96",
|
"@mdi/svg": "7.2.96",
|
||||||
"@polymer/app-layout": "3.1.0",
|
"@polymer/app-layout": "3.1.0",
|
||||||
@ -112,7 +112,7 @@
|
|||||||
"deep-freeze": "0.0.1",
|
"deep-freeze": "0.0.1",
|
||||||
"fuse.js": "6.6.2",
|
"fuse.js": "6.6.2",
|
||||||
"google-timezones-json": "1.1.0",
|
"google-timezones-json": "1.1.0",
|
||||||
"hls.js": "1.4.6",
|
"hls.js": "1.4.7",
|
||||||
"home-assistant-js-websocket": "8.1.0",
|
"home-assistant-js-websocket": "8.1.0",
|
||||||
"idb-keyval": "6.2.1",
|
"idb-keyval": "6.2.1",
|
||||||
"intl-messageformat": "10.5.0",
|
"intl-messageformat": "10.5.0",
|
||||||
@ -203,7 +203,7 @@
|
|||||||
"esprima": "4.0.1",
|
"esprima": "4.0.1",
|
||||||
"fancy-log": "2.0.0",
|
"fancy-log": "2.0.0",
|
||||||
"fs-extra": "11.1.1",
|
"fs-extra": "11.1.1",
|
||||||
"glob": "10.3.0",
|
"glob": "10.3.1",
|
||||||
"gulp": "4.0.2",
|
"gulp": "4.0.2",
|
||||||
"gulp-flatmap": "1.0.2",
|
"gulp-flatmap": "1.0.2",
|
||||||
"gulp-json-transform": "0.4.8",
|
"gulp-json-transform": "0.4.8",
|
||||||
@ -214,7 +214,7 @@
|
|||||||
"husky": "8.0.3",
|
"husky": "8.0.3",
|
||||||
"instant-mocha": "1.5.1",
|
"instant-mocha": "1.5.1",
|
||||||
"jszip": "3.10.1",
|
"jszip": "3.10.1",
|
||||||
"lint-staged": "13.2.2",
|
"lint-staged": "13.2.3",
|
||||||
"lit-analyzer": "2.0.0-pre.3",
|
"lit-analyzer": "2.0.0-pre.3",
|
||||||
"lodash.template": "4.5.0",
|
"lodash.template": "4.5.0",
|
||||||
"magic-string": "0.30.0",
|
"magic-string": "0.30.0",
|
||||||
@ -236,10 +236,10 @@
|
|||||||
"tar": "6.1.15",
|
"tar": "6.1.15",
|
||||||
"terser-webpack-plugin": "5.3.9",
|
"terser-webpack-plugin": "5.3.9",
|
||||||
"ts-lit-plugin": "2.0.0-pre.1",
|
"ts-lit-plugin": "2.0.0-pre.1",
|
||||||
"typescript": "5.1.3",
|
"typescript": "5.1.6",
|
||||||
"vinyl-buffer": "1.0.1",
|
"vinyl-buffer": "1.0.1",
|
||||||
"vinyl-source-stream": "2.0.0",
|
"vinyl-source-stream": "2.0.0",
|
||||||
"webpack": "5.88.0",
|
"webpack": "5.88.1",
|
||||||
"webpack-cli": "5.1.4",
|
"webpack-cli": "5.1.4",
|
||||||
"webpack-dev-server": "4.15.1",
|
"webpack-dev-server": "4.15.1",
|
||||||
"webpack-manifest-plugin": "5.0.0",
|
"webpack-manifest-plugin": "5.0.0",
|
||||||
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "home-assistant-frontend"
|
name = "home-assistant-frontend"
|
||||||
version = "20230630.0"
|
version = "20230703.0"
|
||||||
license = {text = "Apache-2.0"}
|
license = {text = "Apache-2.0"}
|
||||||
description = "The Home Assistant frontend"
|
description = "The Home Assistant frontend"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
27
src/common/string/format-list.ts
Normal file
27
src/common/string/format-list.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import memoizeOne from "memoize-one";
|
||||||
|
import "../../resources/intl-polyfill";
|
||||||
|
import { FrontendLocaleData } from "../../data/translation";
|
||||||
|
|
||||||
|
export const formatListWithAnds = (
|
||||||
|
locale: FrontendLocaleData,
|
||||||
|
list: string[]
|
||||||
|
) => formatConjunctionList(locale).format(list);
|
||||||
|
|
||||||
|
export const formatListWithOrs = (locale: FrontendLocaleData, list: string[]) =>
|
||||||
|
formatDisjunctionList(locale).format(list);
|
||||||
|
|
||||||
|
const formatConjunctionList = memoizeOne(
|
||||||
|
(locale: FrontendLocaleData) =>
|
||||||
|
new Intl.ListFormat(locale.language, {
|
||||||
|
style: "long",
|
||||||
|
type: "conjunction",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const formatDisjunctionList = memoizeOne(
|
||||||
|
(locale: FrontendLocaleData) =>
|
||||||
|
new Intl.ListFormat(locale.language, {
|
||||||
|
style: "long",
|
||||||
|
type: "disjunction",
|
||||||
|
})
|
||||||
|
);
|
@ -12,6 +12,7 @@ import {
|
|||||||
} from "../common/entity/compute_attribute_display";
|
} from "../common/entity/compute_attribute_display";
|
||||||
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
import { computeStateDisplay } from "../common/entity/compute_state_display";
|
||||||
import { computeStateName } from "../common/entity/compute_state_name";
|
import { computeStateName } from "../common/entity/compute_state_name";
|
||||||
|
import "../resources/intl-polyfill";
|
||||||
import type { HomeAssistant } from "../types";
|
import type { HomeAssistant } from "../types";
|
||||||
import { Condition, ForDict, Trigger } from "./automation";
|
import { Condition, ForDict, Trigger } from "./automation";
|
||||||
import {
|
import {
|
||||||
@ -21,7 +22,6 @@ import {
|
|||||||
localizeDeviceAutomationTrigger,
|
localizeDeviceAutomationTrigger,
|
||||||
} from "./device_automation";
|
} from "./device_automation";
|
||||||
import { EntityRegistryEntry } from "./entity_registry";
|
import { EntityRegistryEntry } from "./entity_registry";
|
||||||
import "../resources/intl-polyfill";
|
|
||||||
import { FrontendLocaleData } from "./translation";
|
import { FrontendLocaleData } from "./translation";
|
||||||
|
|
||||||
const triggerTranslationBaseKey =
|
const triggerTranslationBaseKey =
|
||||||
|
@ -31,6 +31,10 @@ import {
|
|||||||
VariablesAction,
|
VariablesAction,
|
||||||
WaitForTriggerAction,
|
WaitForTriggerAction,
|
||||||
} from "./script";
|
} from "./script";
|
||||||
|
import { formatListWithAnds } from "../common/string/format-list";
|
||||||
|
|
||||||
|
const actionTranslationBaseKey =
|
||||||
|
"ui.panel.config.automation.editor.actions.type";
|
||||||
|
|
||||||
export const describeAction = <T extends ActionType>(
|
export const describeAction = <T extends ActionType>(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
@ -75,25 +79,8 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
if (actionType === "service") {
|
if (actionType === "service") {
|
||||||
const config = action as ActionTypes["service"];
|
const config = action as ActionTypes["service"];
|
||||||
|
|
||||||
let base: string | undefined;
|
const targets: string[] = [];
|
||||||
|
|
||||||
if (
|
|
||||||
config.service_template ||
|
|
||||||
(config.service && isTemplate(config.service))
|
|
||||||
) {
|
|
||||||
base = "Call a service based on a template";
|
|
||||||
} else if (config.service) {
|
|
||||||
const [domain, serviceName] = config.service.split(".", 2);
|
|
||||||
const service = hass.services[domain][serviceName];
|
|
||||||
base = service
|
|
||||||
? `${domainToName(hass.localize, domain)}: ${service.name}`
|
|
||||||
: `Call service: ${config.service}`;
|
|
||||||
} else {
|
|
||||||
return "Call a service";
|
|
||||||
}
|
|
||||||
if (config.target) {
|
if (config.target) {
|
||||||
const targets: string[] = [];
|
|
||||||
|
|
||||||
for (const [key, label] of Object.entries({
|
for (const [key, label] of Object.entries({
|
||||||
area_id: "areas",
|
area_id: "areas",
|
||||||
device_id: "devices",
|
device_id: "devices",
|
||||||
@ -108,7 +95,12 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
|
|
||||||
for (const targetThing of keyConf) {
|
for (const targetThing of keyConf) {
|
||||||
if (isTemplate(targetThing)) {
|
if (isTemplate(targetThing)) {
|
||||||
targets.push(`templated ${label}`);
|
targets.push(
|
||||||
|
hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.target_template`,
|
||||||
|
{ name: label }
|
||||||
|
)
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
} else if (key === "entity_id") {
|
} else if (key === "entity_id") {
|
||||||
if (targetThing.includes(".")) {
|
if (targetThing.includes(".")) {
|
||||||
@ -125,7 +117,11 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
computeEntityRegistryName(hass, entityReg) || targetThing
|
computeEntityRegistryName(hass, entityReg) || targetThing
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
targets.push("unknown entity");
|
targets.push(
|
||||||
|
hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.target_unknown_entity`
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (key === "device_id") {
|
} else if (key === "device_id") {
|
||||||
@ -133,46 +129,105 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
if (device) {
|
if (device) {
|
||||||
targets.push(computeDeviceName(device, hass));
|
targets.push(computeDeviceName(device, hass));
|
||||||
} else {
|
} else {
|
||||||
targets.push("unknown device");
|
targets.push(
|
||||||
|
hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.target_unknown_device`
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if (key === "area_id") {
|
} else if (key === "area_id") {
|
||||||
const area = hass.areas[targetThing];
|
const area = hass.areas[targetThing];
|
||||||
if (area?.name) {
|
if (area?.name) {
|
||||||
targets.push(area.name);
|
targets.push(area.name);
|
||||||
} else {
|
} else {
|
||||||
targets.push("unknown area");
|
targets.push(
|
||||||
|
hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.target_unknown_area`
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targets.push(targetThing);
|
targets.push(targetThing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targets.length > 0) {
|
|
||||||
base += ` ${targets.join(", ")}`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return base;
|
if (
|
||||||
|
config.service_template ||
|
||||||
|
(config.service && isTemplate(config.service))
|
||||||
|
) {
|
||||||
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.service_based_on_template`,
|
||||||
|
{ targets: formatListWithAnds(hass.locale, targets) }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.service) {
|
||||||
|
const [domain, serviceName] = config.service.split(".", 2);
|
||||||
|
const service = hass.services[domain][serviceName];
|
||||||
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.service_based_on_name`,
|
||||||
|
{
|
||||||
|
name: service
|
||||||
|
? `${domainToName(hass.localize, domain)}: ${service.name}`
|
||||||
|
: config.service,
|
||||||
|
targets: formatListWithAnds(hass.locale, targets),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.service.description.service`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "delay") {
|
if (actionType === "delay") {
|
||||||
const config = action as DelayAction;
|
const config = action as DelayAction;
|
||||||
|
|
||||||
let duration: string;
|
let duration: string;
|
||||||
|
|
||||||
if (typeof config.delay === "number") {
|
if (typeof config.delay === "number") {
|
||||||
duration = `for ${secondsToDuration(config.delay)!}`;
|
duration = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||||
|
{
|
||||||
|
duration: secondsToDuration(config.delay)!,
|
||||||
|
}
|
||||||
|
);
|
||||||
} else if (typeof config.delay === "string") {
|
} else if (typeof config.delay === "string") {
|
||||||
duration = isTemplate(config.delay)
|
duration = isTemplate(config.delay)
|
||||||
? "based on a template"
|
? hass.localize(
|
||||||
: `for ${config.delay || "a duration"}`;
|
`${actionTranslationBaseKey}.delay.description.duration_template`
|
||||||
|
)
|
||||||
|
: hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||||
|
{
|
||||||
|
duration:
|
||||||
|
config.delay ||
|
||||||
|
hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.delay.description.duration_unknown`
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
} else if (config.delay) {
|
} else if (config.delay) {
|
||||||
duration = `for ${formatDuration(config.delay)}`;
|
duration = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||||
|
{
|
||||||
|
duration: formatDuration(config.delay),
|
||||||
|
}
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
duration = "for a duration";
|
duration = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.delay.description.duration_string`,
|
||||||
|
{
|
||||||
|
duration: hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.delay.description.duration_unknown`
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return `Delay ${duration}`;
|
return hass.localize(`${actionTranslationBaseKey}.delay.description.full`, {
|
||||||
|
duration: duration,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "activate_scene") {
|
if (actionType === "activate_scene") {
|
||||||
@ -184,77 +239,139 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
entityId = config.target?.entity_id || config.entity_id;
|
entityId = config.target?.entity_id || config.entity_id;
|
||||||
}
|
}
|
||||||
if (!entityId) {
|
if (!entityId) {
|
||||||
return "Activate a scene";
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.activate_scene.description.activate_scene`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
const sceneStateObj = entityId ? hass.states[entityId] : undefined;
|
const sceneStateObj = entityId ? hass.states[entityId] : undefined;
|
||||||
return `Activate scene ${
|
return hass.localize(
|
||||||
sceneStateObj ? computeStateName(sceneStateObj) : entityId
|
`${actionTranslationBaseKey}.activate_scene.description.activate_scene_with_name`,
|
||||||
}`;
|
{ name: sceneStateObj ? computeStateName(sceneStateObj) : entityId }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "play_media") {
|
if (actionType === "play_media") {
|
||||||
const config = action as PlayMediaAction;
|
const config = action as PlayMediaAction;
|
||||||
const entityId = config.target?.entity_id || config.entity_id;
|
const entityId = config.target?.entity_id || config.entity_id;
|
||||||
const mediaStateObj = entityId ? hass.states[entityId] : undefined;
|
const mediaStateObj = entityId ? hass.states[entityId] : undefined;
|
||||||
return `Play ${
|
return hass.localize(
|
||||||
config.metadata.title || config.data.media_content_id || "media"
|
`${actionTranslationBaseKey}.play_media.description.full`,
|
||||||
} on ${
|
{
|
||||||
mediaStateObj
|
hasMedia: config.metadata.title || config.data.media_content_id,
|
||||||
? computeStateName(mediaStateObj)
|
media: config.metadata.title || config.data.media_content_id,
|
||||||
: entityId || "a media player"
|
hasMediaPlayer: mediaStateObj ? true : entityId !== undefined,
|
||||||
}`;
|
mediaPlayer: mediaStateObj ? computeStateName(mediaStateObj) : entityId,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "wait_for_trigger") {
|
if (actionType === "wait_for_trigger") {
|
||||||
const config = action as WaitForTriggerAction;
|
const config = action as WaitForTriggerAction;
|
||||||
const triggers = ensureArray(config.wait_for_trigger);
|
const triggers = ensureArray(config.wait_for_trigger);
|
||||||
if (!triggers || triggers.length === 0) {
|
if (!triggers || triggers.length === 0) {
|
||||||
return "Wait for a trigger";
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.wait_for_trigger.description.wait_for_a_trigger`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return `Wait for ${triggers
|
const triggerNames = triggers.map((trigger) =>
|
||||||
.map((trigger) => describeTrigger(trigger, hass, entityRegistry))
|
describeTrigger(trigger, hass, entityRegistry)
|
||||||
.join(", ")}`;
|
);
|
||||||
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.wait_for_trigger.description.wait_for_triggers_with_name`,
|
||||||
|
{ triggers: formatListWithAnds(hass.locale, triggerNames) }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "variables") {
|
if (actionType === "variables") {
|
||||||
const config = action as VariablesAction;
|
const config = action as VariablesAction;
|
||||||
return `Define variables ${Object.keys(config.variables).join(", ")}`;
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.variables.description.full`,
|
||||||
|
{
|
||||||
|
names: formatListWithAnds(hass.locale, Object.keys(config.variables)),
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "fire_event") {
|
if (actionType === "fire_event") {
|
||||||
const config = action as EventAction;
|
const config = action as EventAction;
|
||||||
if (isTemplate(config.event)) {
|
if (isTemplate(config.event)) {
|
||||||
return "Fire event based on a template";
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.event.description.full`,
|
||||||
|
{
|
||||||
|
name: hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.event.description.template`
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return `Fire event ${config.event}`;
|
return hass.localize(`${actionTranslationBaseKey}.event.description.full`, {
|
||||||
|
name: config.event,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "wait_template") {
|
if (actionType === "wait_template") {
|
||||||
return "Wait for a template to render true";
|
return hass.localize(
|
||||||
}
|
`${actionTranslationBaseKey}.wait_template.description.full`
|
||||||
|
);
|
||||||
if (actionType === "check_condition") {
|
|
||||||
return describeCondition(action as Condition, hass, entityRegistry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "stop") {
|
if (actionType === "stop") {
|
||||||
const config = action as StopAction;
|
const config = action as StopAction;
|
||||||
return `Stop${config.stop ? ` because: ${config.stop}` : ""}`;
|
return hass.localize(`${actionTranslationBaseKey}.stop.description.full`, {
|
||||||
|
hasReason: config.stop !== undefined,
|
||||||
|
reason: config.stop,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "if") {
|
if (actionType === "if") {
|
||||||
const config = action as IfAction;
|
const config = action as IfAction;
|
||||||
return `Perform an action if: ${
|
|
||||||
!config.if
|
let ifConditions: string[] = [];
|
||||||
? ""
|
if (Array.isArray(config.if)) {
|
||||||
: typeof config.if === "string"
|
const conditions = ensureArray(config.if);
|
||||||
? config.if
|
conditions.forEach((condition) => {
|
||||||
: ensureArray(config.if).length > 1
|
ifConditions.push(describeCondition(condition, hass, entityRegistry));
|
||||||
? `${ensureArray(config.if).length} conditions`
|
});
|
||||||
: ensureArray(config.if).length
|
} else {
|
||||||
? describeCondition(ensureArray(config.if)[0], hass, entityRegistry)
|
ifConditions = [config.if];
|
||||||
: ""
|
}
|
||||||
}${config.else ? " (or else!)" : ""}`;
|
|
||||||
|
let elseActions: string[] = [];
|
||||||
|
if (config.else) {
|
||||||
|
if (Array.isArray(config.else)) {
|
||||||
|
const actions = ensureArray(config.else);
|
||||||
|
actions.forEach((currentAction) => {
|
||||||
|
elseActions.push(
|
||||||
|
describeAction(hass, entityRegistry, currentAction, undefined)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
elseActions = [
|
||||||
|
describeAction(hass, entityRegistry, config.else, undefined),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let thenActions: string[] = [];
|
||||||
|
if (Array.isArray(config.then)) {
|
||||||
|
const actions = ensureArray(config.then);
|
||||||
|
actions.forEach((currentAction) => {
|
||||||
|
thenActions.push(
|
||||||
|
describeAction(hass, entityRegistry, currentAction, undefined)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
thenActions = [
|
||||||
|
describeAction(hass, entityRegistry, config.then, undefined),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return hass.localize(`${actionTranslationBaseKey}.if.description.full`, {
|
||||||
|
hasElse: config.else !== undefined,
|
||||||
|
action: formatListWithAnds(hass.locale, thenActions),
|
||||||
|
conditions: formatListWithAnds(hass.locale, ifConditions),
|
||||||
|
elseAction: formatListWithAnds(hass.locale, elseActions),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "choose") {
|
if (actionType === "choose") {
|
||||||
@ -262,42 +379,64 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
if (config.choose) {
|
if (config.choose) {
|
||||||
const numActions =
|
const numActions =
|
||||||
ensureArray(config.choose).length + (config.default ? 1 : 0);
|
ensureArray(config.choose).length + (config.default ? 1 : 0);
|
||||||
return `Choose between ${numActions} action${
|
return hass.localize(
|
||||||
numActions === 1 ? "" : "s"
|
`${actionTranslationBaseKey}.choose.description.full`,
|
||||||
}`;
|
{ number: numActions }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return "Choose an action";
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.choose.description.no_action`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "repeat") {
|
if (actionType === "repeat") {
|
||||||
const config = action as RepeatAction;
|
const config = action as RepeatAction;
|
||||||
|
|
||||||
let base = "Repeat an action";
|
let chosenAction = "";
|
||||||
if ("count" in config.repeat) {
|
if ("count" in config.repeat) {
|
||||||
const count = config.repeat.count;
|
const count = config.repeat.count;
|
||||||
base += ` ${count} time${Number(count) === 1 ? "" : "s"}`;
|
chosenAction = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.repeat.description.count`,
|
||||||
|
{ count: count }
|
||||||
|
);
|
||||||
} else if ("while" in config.repeat) {
|
} else if ("while" in config.repeat) {
|
||||||
base += ` while ${ensureArray(config.repeat.while)
|
const conditions = ensureArray(config.repeat.while).map((condition) =>
|
||||||
.map((condition) => describeCondition(condition, hass, entityRegistry))
|
describeCondition(condition, hass, entityRegistry)
|
||||||
.join(", ")} is true`;
|
);
|
||||||
|
chosenAction = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.repeat.description.while`,
|
||||||
|
{ conditions: formatListWithAnds(hass.locale, conditions) }
|
||||||
|
);
|
||||||
} else if ("until" in config.repeat) {
|
} else if ("until" in config.repeat) {
|
||||||
base += ` until ${ensureArray(config.repeat.until)
|
const conditions = ensureArray(config.repeat.until).map((condition) =>
|
||||||
.map((condition) => describeCondition(condition, hass, entityRegistry))
|
describeCondition(condition, hass, entityRegistry)
|
||||||
.join(", ")} is true`;
|
);
|
||||||
|
chosenAction = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.repeat.description.until`,
|
||||||
|
{ conditions: formatListWithAnds(hass.locale, conditions) }
|
||||||
|
);
|
||||||
} else if ("for_each" in config.repeat) {
|
} else if ("for_each" in config.repeat) {
|
||||||
base += ` for every item: ${ensureArray(config.repeat.for_each)
|
const items = ensureArray(config.repeat.for_each).map((item) =>
|
||||||
.map((item) => JSON.stringify(item))
|
JSON.stringify(item)
|
||||||
.join(", ")}`;
|
);
|
||||||
|
chosenAction = hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.repeat.description.for_each`,
|
||||||
|
{ items: formatListWithAnds(hass.locale, items) }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return base;
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.repeat.description.full`,
|
||||||
|
{ chosenAction: chosenAction }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "check_condition") {
|
if (actionType === "check_condition") {
|
||||||
return `Test ${describeCondition(
|
return hass.localize(
|
||||||
action as Condition,
|
`${actionTranslationBaseKey}.check_condition.description.full`,
|
||||||
hass,
|
{
|
||||||
entityRegistry
|
condition: describeCondition(action as Condition, hass, entityRegistry),
|
||||||
)}`;
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actionType === "device_action") {
|
if (actionType === "device_action") {
|
||||||
@ -313,7 +452,7 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
if (localized) {
|
if (localized) {
|
||||||
return localized;
|
return localized;
|
||||||
}
|
}
|
||||||
const stateObj = hass.states[config.entity_id as string];
|
const stateObj = hass.states[config.entity_id];
|
||||||
return `${config.type || "Perform action with"} ${
|
return `${config.type || "Perform action with"} ${
|
||||||
stateObj ? computeStateName(stateObj) : config.entity_id
|
stateObj ? computeStateName(stateObj) : config.entity_id
|
||||||
}`;
|
}`;
|
||||||
@ -322,7 +461,10 @@ const tryDescribeAction = <T extends ActionType>(
|
|||||||
if (actionType === "parallel") {
|
if (actionType === "parallel") {
|
||||||
const config = action as ParallelAction;
|
const config = action as ParallelAction;
|
||||||
const numActions = ensureArray(config.parallel).length;
|
const numActions = ensureArray(config.parallel).length;
|
||||||
return `Run ${numActions} action${numActions === 1 ? "" : "s"} in parallel`;
|
return hass.localize(
|
||||||
|
`${actionTranslationBaseKey}.parallel.description.full`,
|
||||||
|
{ number: numActions }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return actionType;
|
return actionType;
|
||||||
|
@ -132,3 +132,6 @@ export const getSupervisorEventCollection = (
|
|||||||
subscribeSupervisorEventUpdates(connection, store, key),
|
subscribeSupervisorEventUpdates(connection, store, key),
|
||||||
{ unsubGrace: false }
|
{ unsubGrace: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const cleanupSupervisorCollection = (conn: Connection, key: string) =>
|
||||||
|
delete conn[`_supervisor${key}Event`];
|
||||||
|
@ -15,7 +15,6 @@ import {
|
|||||||
mdiStopCircleOutline,
|
mdiStopCircleOutline,
|
||||||
} from "@mdi/js";
|
} from "@mdi/js";
|
||||||
import deepClone from "deep-clone-simple";
|
import deepClone from "deep-clone-simple";
|
||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
@ -26,6 +25,7 @@ import {
|
|||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
|
import { consume } from "@lit-labs/context";
|
||||||
import { storage } from "../../../../common/decorators/storage";
|
import { storage } from "../../../../common/decorators/storage";
|
||||||
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
@ -40,10 +40,7 @@ import type { HaYamlEditor } from "../../../../components/ha-yaml-editor";
|
|||||||
import { ACTION_TYPES, YAML_ONLY_ACTION_TYPES } from "../../../../data/action";
|
import { ACTION_TYPES, YAML_ONLY_ACTION_TYPES } from "../../../../data/action";
|
||||||
import { AutomationClipboard } from "../../../../data/automation";
|
import { AutomationClipboard } from "../../../../data/automation";
|
||||||
import { validateConfig } from "../../../../data/config";
|
import { validateConfig } from "../../../../data/config";
|
||||||
import {
|
import { EntityRegistryEntry } from "../../../../data/entity_registry";
|
||||||
EntityRegistryEntry,
|
|
||||||
subscribeEntityRegistry,
|
|
||||||
} from "../../../../data/entity_registry";
|
|
||||||
import {
|
import {
|
||||||
Action,
|
Action,
|
||||||
NonConditionAction,
|
NonConditionAction,
|
||||||
@ -73,6 +70,7 @@ import "./types/ha-automation-action-service";
|
|||||||
import "./types/ha-automation-action-stop";
|
import "./types/ha-automation-action-stop";
|
||||||
import "./types/ha-automation-action-wait_for_trigger";
|
import "./types/ha-automation-action-wait_for_trigger";
|
||||||
import "./types/ha-automation-action-wait_template";
|
import "./types/ha-automation-action-wait_template";
|
||||||
|
import { fullEntitiesContext } from "../../../../data/context";
|
||||||
|
|
||||||
export const getType = (action: Action | undefined) => {
|
export const getType = (action: Action | undefined) => {
|
||||||
if (!action) {
|
if (!action) {
|
||||||
@ -137,7 +135,9 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
})
|
})
|
||||||
public _clipboard?: AutomationClipboard;
|
public _clipboard?: AutomationClipboard;
|
||||||
|
|
||||||
@state() private _entityReg: EntityRegistryEntry[] = [];
|
@state()
|
||||||
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
@state() private _warnings?: string[];
|
@state() private _warnings?: string[];
|
||||||
|
|
||||||
@ -147,14 +147,6 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
|
|
||||||
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
|
@query("ha-yaml-editor") private _yamlEditor?: HaYamlEditor;
|
||||||
|
|
||||||
public hassSubscribe(): UnsubscribeFunc[] {
|
|
||||||
return [
|
|
||||||
subscribeEntityRegistry(this.hass.connection!, (entities) => {
|
|
||||||
this._entityReg = entities;
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected willUpdate(changedProperties: PropertyValues) {
|
protected willUpdate(changedProperties: PropertyValues) {
|
||||||
if (!changedProperties.has("action")) {
|
if (!changedProperties.has("action")) {
|
||||||
return;
|
return;
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { consume } from "@lit-labs/context";
|
|
||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { property, state } from "lit/decorators";
|
import { property, state } from "lit/decorators";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import "../../../../components/ha-chip";
|
import "../../../../components/ha-chip";
|
||||||
import "../../../../components/ha-chip-set";
|
import "../../../../components/ha-chip-set";
|
||||||
import { showAutomationEditor } from "../../../../data/automation";
|
import { showAutomationEditor } from "../../../../data/automation";
|
||||||
import { fullEntitiesContext } from "../../../../data/context";
|
|
||||||
import {
|
import {
|
||||||
DeviceAction,
|
DeviceAction,
|
||||||
DeviceAutomation,
|
DeviceAutomation,
|
||||||
@ -32,11 +30,9 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
|
|
||||||
@property({ attribute: false }) public automations: T[] = [];
|
@property({ attribute: false }) public automations: T[] = [];
|
||||||
|
|
||||||
@state() public _showSecondary = false;
|
@property({ attribute: false }) entityReg?: EntityRegistryEntry[];
|
||||||
|
|
||||||
@state()
|
@state() public _showSecondary = false;
|
||||||
@consume({ context: fullEntitiesContext, subscribe: true })
|
|
||||||
_entityReg!: EntityRegistryEntry[];
|
|
||||||
|
|
||||||
abstract headerKey: Parameters<typeof this.hass.localize>[0];
|
abstract headerKey: Parameters<typeof this.hass.localize>[0];
|
||||||
|
|
||||||
@ -67,7 +63,7 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
if (this.automations.length === 0) {
|
if (this.automations.length === 0 || !this.entityReg) {
|
||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
const automations = this._showSecondary
|
const automations = this._showSecondary
|
||||||
@ -89,7 +85,7 @@ export abstract class HaDeviceAutomationCard<
|
|||||||
>
|
>
|
||||||
${this._localizeDeviceAutomation(
|
${this._localizeDeviceAutomation(
|
||||||
this.hass,
|
this.hass,
|
||||||
this._entityReg,
|
this.entityReg!,
|
||||||
automation
|
automation
|
||||||
)}
|
)}
|
||||||
</ha-chip>
|
</ha-chip>
|
||||||
|
@ -109,6 +109,7 @@ export class DialogDeviceAutomation extends LitElement {
|
|||||||
<ha-device-triggers-card
|
<ha-device-triggers-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.automations=${this._triggers}
|
.automations=${this._triggers}
|
||||||
|
.entityReg=${this._params.entityReg}
|
||||||
></ha-device-triggers-card>
|
></ha-device-triggers-card>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@ -117,6 +118,7 @@ export class DialogDeviceAutomation extends LitElement {
|
|||||||
<ha-device-conditions-card
|
<ha-device-conditions-card
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.automations=${this._conditions}
|
.automations=${this._conditions}
|
||||||
|
.entityReg=${this._params.entityReg}
|
||||||
></ha-device-conditions-card>
|
></ha-device-conditions-card>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
@ -126,6 +128,7 @@ export class DialogDeviceAutomation extends LitElement {
|
|||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.automations=${this._actions}
|
.automations=${this._actions}
|
||||||
.script=${this._params.script}
|
.script=${this._params.script}
|
||||||
|
.entityReg=${this._params.entityReg}
|
||||||
></ha-device-actions-card>
|
></ha-device-actions-card>
|
||||||
`
|
`
|
||||||
: ""}
|
: ""}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { DeviceRegistryEntry } from "../../../../data/device_registry";
|
import { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||||
|
import { EntityRegistryEntry } from "../../../../data/entity_registry";
|
||||||
|
|
||||||
export interface DeviceAutomationDialogParams {
|
export interface DeviceAutomationDialogParams {
|
||||||
device: DeviceRegistryEntry;
|
device: DeviceRegistryEntry;
|
||||||
|
entityReg: EntityRegistryEntry[];
|
||||||
script?: boolean;
|
script?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import {
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { ifDefined } from "lit/directives/if-defined";
|
import { ifDefined } from "lit/directives/if-defined";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { consume } from "@lit-labs/context";
|
||||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||||
import { SENSOR_ENTITIES } from "../../../common/const";
|
import { SENSOR_ENTITIES } from "../../../common/const";
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
@ -84,6 +85,7 @@ import {
|
|||||||
loadDeviceRegistryDetailDialog,
|
loadDeviceRegistryDetailDialog,
|
||||||
showDeviceRegistryDetailDialog,
|
showDeviceRegistryDetailDialog,
|
||||||
} from "./device-registry-detail/show-dialog-device-registry-detail";
|
} from "./device-registry-detail/show-dialog-device-registry-detail";
|
||||||
|
import { fullEntitiesContext } from "../../../data/context";
|
||||||
|
|
||||||
export interface EntityRegistryStateEntry extends EntityRegistryEntry {
|
export interface EntityRegistryStateEntry extends EntityRegistryEntry {
|
||||||
stateName?: string | null;
|
stateName?: string | null;
|
||||||
@ -137,6 +139,10 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
|
|
||||||
@state() private _deviceAlerts?: DeviceAlert[];
|
@state() private _deviceAlerts?: DeviceAlert[];
|
||||||
|
|
||||||
|
@state()
|
||||||
|
@consume({ context: fullEntitiesContext, subscribe: true })
|
||||||
|
_entityReg!: EntityRegistryEntry[];
|
||||||
|
|
||||||
private _logbookTime = { recent: 86400 };
|
private _logbookTime = { recent: 86400 };
|
||||||
|
|
||||||
private _device = memoizeOne(
|
private _device = memoizeOne(
|
||||||
@ -422,12 +428,13 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
)
|
)
|
||||||
: this.hass.localize(
|
: this.hass.localize(
|
||||||
"ui.panel.config.devices.automation.create",
|
"ui.panel.config.devices.automation.create",
|
||||||
"type",
|
{
|
||||||
this.hass.localize(
|
type: this.hass.localize(
|
||||||
`ui.panel.config.devices.type.${
|
`ui.panel.config.devices.type.${
|
||||||
device.entry_type || "device"
|
device.entry_type || "device"
|
||||||
}`
|
}`
|
||||||
)
|
),
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
.path=${mdiPlusCircle}
|
.path=${mdiPlusCircle}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
@ -1180,6 +1187,7 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
private _showScriptDialog() {
|
private _showScriptDialog() {
|
||||||
showDeviceAutomationDialog(this, {
|
showDeviceAutomationDialog(this, {
|
||||||
device: this._device(this.deviceId, this.devices)!,
|
device: this._device(this.deviceId, this.devices)!,
|
||||||
|
entityReg: this._entityReg,
|
||||||
script: true,
|
script: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1187,6 +1195,7 @@ export class HaConfigDevicePage extends LitElement {
|
|||||||
private _showAutomationDialog() {
|
private _showAutomationDialog() {
|
||||||
showDeviceAutomationDialog(this, {
|
showDeviceAutomationDialog(this, {
|
||||||
device: this._device(this.deviceId, this.devices)!,
|
device: this._device(this.deviceId, this.devices)!,
|
||||||
|
entityReg: this._entityReg,
|
||||||
script: false,
|
script: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -77,10 +77,13 @@ export class HaIntegrationActionCard extends LitElement {
|
|||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
h3 {
|
h3 {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.header-button {
|
.header-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -24,8 +24,6 @@ import { classMap } from "lit/directives/class-map";
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-next";
|
|
||||||
import "../../../components/ha-list-item";
|
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import { ConfigEntry, ERROR_STATES } from "../../../data/config_entries";
|
import { ConfigEntry, ERROR_STATES } from "../../../data/config_entries";
|
||||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||||
@ -114,12 +112,6 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
: undefined}
|
: undefined}
|
||||||
.manifest=${this.manifest}
|
.manifest=${this.manifest}
|
||||||
>
|
>
|
||||||
<ha-icon-next
|
|
||||||
slot="header-button"
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.integrations.config_entry.configure"
|
|
||||||
)}
|
|
||||||
></ha-icon-next>
|
|
||||||
</ha-integration-header>
|
</ha-integration-header>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@ -345,9 +337,6 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: var(--primary-text-color);
|
color: var(--primary-text-color);
|
||||||
}
|
}
|
||||||
a ha-icon-next {
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
.icons {
|
.icons {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { mdiAlertCircleOutline, mdiAlertOutline } from "@mdi/js";
|
import { mdiAlertCircleOutline, mdiAlertOutline } from "@mdi/js";
|
||||||
import { LitElement, TemplateResult, css, html, nothing } from "lit";
|
import { LitElement, TemplateResult, css, html, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import "../../../components/ha-icon-next";
|
||||||
import "../../../components/ha-svg-icon";
|
import "../../../components/ha-svg-icon";
|
||||||
import { IntegrationManifest, domainToName } from "../../../data/integration";
|
import { IntegrationManifest, domainToName } from "../../../data/integration";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
@ -40,27 +41,34 @@ export class HaIntegrationHeader extends LitElement {
|
|||||||
/>
|
/>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div
|
<div
|
||||||
class="primary ${this.warning || this.error ? "hasError" : ""}"
|
class="primary ${this.warning || this.error ? "has-secondary" : ""}"
|
||||||
role="heading"
|
role="heading"
|
||||||
aria-level="1"
|
aria-level="1"
|
||||||
>
|
>
|
||||||
${domainName}
|
${domainName}
|
||||||
</div>
|
</div>
|
||||||
${this.error
|
${this.error
|
||||||
? html`<div class="error">
|
? html`
|
||||||
<ha-svg-icon .path=${mdiAlertCircleOutline}></ha-svg-icon>${this
|
<div class="secondary error">
|
||||||
.error}
|
<ha-svg-icon .path=${mdiAlertCircleOutline}></ha-svg-icon>
|
||||||
</div>`
|
<span>${this.error}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
: this.warning
|
: this.warning
|
||||||
? html`<div class="warning">
|
? html`
|
||||||
<ha-svg-icon .path=${mdiAlertOutline}></ha-svg-icon>${this
|
<div class="secondary warning">
|
||||||
.warning}
|
<ha-svg-icon .path=${mdiAlertOutline}></ha-svg-icon>
|
||||||
</div>`
|
<span>${this.warning}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
</div>
|
</div>
|
||||||
<div class="header-button">
|
<ha-icon-next
|
||||||
<slot name="header-button"></slot>
|
class="header-button"
|
||||||
</div>
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_entry.configure"
|
||||||
|
)}
|
||||||
|
></ha-icon-next>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -76,12 +84,15 @@ export class HaIntegrationHeader extends LitElement {
|
|||||||
static styles = css`
|
static styles = css`
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 16px;
|
padding-top: 16px;
|
||||||
padding-bottom: 16px;
|
padding-bottom: 16px;
|
||||||
padding-inline-start: 16px;
|
padding-inline-start: 16px;
|
||||||
padding-inline-end: 8px;
|
padding-inline-end: 8px;
|
||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
|
box-sizing: border-box;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.header img {
|
.header img {
|
||||||
margin-inline-start: initial;
|
margin-inline-start: initial;
|
||||||
@ -91,50 +102,55 @@ export class HaIntegrationHeader extends LitElement {
|
|||||||
direction: var(--direction);
|
direction: var(--direction);
|
||||||
}
|
}
|
||||||
.header .info {
|
.header .info {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
.primary,
|
ha-icon-next {
|
||||||
.warning,
|
color: var(--secondary-text-color);
|
||||||
.error {
|
|
||||||
word-wrap: break-word;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
}
|
||||||
.primary {
|
.primary {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
word-break: break-word;
|
|
||||||
color: var(--primary-text-color);
|
color: var(--primary-text-color);
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
}
|
}
|
||||||
.hasError {
|
.has-secondary {
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
.warning,
|
.secondary {
|
||||||
.error {
|
min-width: 0;
|
||||||
line-height: 20px;
|
|
||||||
--mdc-icon-size: 20px;
|
--mdc-icon-size: 20px;
|
||||||
-webkit-line-clamp: 1;
|
-webkit-line-clamp: 1;
|
||||||
font-size: 0.9em;
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.secondary > span {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.secondary > ha-svg-icon {
|
||||||
|
margin-right: 4px;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.error ha-svg-icon {
|
.error ha-svg-icon {
|
||||||
margin-right: 4px;
|
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
}
|
}
|
||||||
.warning ha-svg-icon {
|
.warning ha-svg-icon {
|
||||||
margin-right: 4px;
|
|
||||||
color: var(--warning-color);
|
color: var(--warning-color);
|
||||||
}
|
}
|
||||||
.header-button {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 36px;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -336,11 +336,15 @@ class ViewMountDialog extends LitElement {
|
|||||||
private async _connectMount() {
|
private async _connectMount() {
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
this._waiting = true;
|
this._waiting = true;
|
||||||
|
const mountData = { ...this._data! };
|
||||||
|
if (mountData.type === "cifs" && mountData.version === "auto") {
|
||||||
|
mountData.version = undefined;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (this._existing) {
|
if (this._existing) {
|
||||||
await updateSupervisorMount(this.hass, this._data!);
|
await updateSupervisorMount(this.hass, mountData);
|
||||||
} else {
|
} else {
|
||||||
await createSupervisorMount(this.hass, this._data!);
|
await createSupervisorMount(this.hass, mountData);
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this._error = extractApiErrorMessage(err);
|
this._error = extractApiErrorMessage(err);
|
||||||
|
@ -21,6 +21,10 @@ import type { LovelaceCard } from "../../types";
|
|||||||
import { severityMap } from "../hui-gauge-card";
|
import { severityMap } from "../hui-gauge-card";
|
||||||
import type { EnergyCarbonGaugeCardConfig } from "../types";
|
import type { EnergyCarbonGaugeCardConfig } from "../types";
|
||||||
|
|
||||||
|
const FORMAT_OPTIONS = {
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("hui-energy-carbon-consumed-gauge-card")
|
@customElement("hui-energy-carbon-consumed-gauge-card")
|
||||||
class HuiEnergyCarbonGaugeCard
|
class HuiEnergyCarbonGaugeCard
|
||||||
extends SubscribeMixin(LitElement)
|
extends SubscribeMixin(LitElement)
|
||||||
@ -129,6 +133,7 @@ class HuiEnergyCarbonGaugeCard
|
|||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
.value=${value}
|
.value=${value}
|
||||||
|
.formatOptions=${FORMAT_OPTIONS}
|
||||||
.locale=${this.hass.locale}
|
.locale=${this.hass.locale}
|
||||||
label="%"
|
label="%"
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
|
@ -19,6 +19,10 @@ import type { LovelaceCard } from "../../types";
|
|||||||
import { severityMap } from "../hui-gauge-card";
|
import { severityMap } from "../hui-gauge-card";
|
||||||
import type { EnergySelfSufficiencyGaugeCardConfig } from "../types";
|
import type { EnergySelfSufficiencyGaugeCardConfig } from "../types";
|
||||||
|
|
||||||
|
const FORMAT_OPTIONS = {
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("hui-energy-self-sufficiency-gauge-card")
|
@customElement("hui-energy-self-sufficiency-gauge-card")
|
||||||
class HuiEnergySelfSufficiencyGaugeCard
|
class HuiEnergySelfSufficiencyGaugeCard
|
||||||
extends SubscribeMixin(LitElement)
|
extends SubscribeMixin(LitElement)
|
||||||
@ -174,8 +178,9 @@ class HuiEnergySelfSufficiencyGaugeCard
|
|||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
.value=${value}
|
.value=${value}
|
||||||
.locale=${this.hass.locale}
|
|
||||||
label="%"
|
label="%"
|
||||||
|
.formatOptions=${FORMAT_OPTIONS}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
"--gauge-color": this._computeSeverity(value),
|
"--gauge-color": this._computeSeverity(value),
|
||||||
})}
|
})}
|
||||||
|
@ -19,6 +19,10 @@ import type { LovelaceCard } from "../../types";
|
|||||||
import { severityMap } from "../hui-gauge-card";
|
import { severityMap } from "../hui-gauge-card";
|
||||||
import type { EnergySolarGaugeCardConfig } from "../types";
|
import type { EnergySolarGaugeCardConfig } from "../types";
|
||||||
|
|
||||||
|
const FORMAT_OPTIONS = {
|
||||||
|
maximumFractionDigits: 0,
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("hui-energy-solar-consumed-gauge-card")
|
@customElement("hui-energy-solar-consumed-gauge-card")
|
||||||
class HuiEnergySolarGaugeCard
|
class HuiEnergySolarGaugeCard
|
||||||
extends SubscribeMixin(LitElement)
|
extends SubscribeMixin(LitElement)
|
||||||
@ -109,8 +113,9 @@ class HuiEnergySolarGaugeCard
|
|||||||
min="0"
|
min="0"
|
||||||
max="100"
|
max="100"
|
||||||
.value=${value}
|
.value=${value}
|
||||||
.locale=${this.hass.locale}
|
|
||||||
label="%"
|
label="%"
|
||||||
|
.formatOptions=${FORMAT_OPTIONS}
|
||||||
|
.locale=${this.hass.locale}
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
"--gauge-color": this._computeSeverity(value),
|
"--gauge-color": this._computeSeverity(value),
|
||||||
})}
|
})}
|
||||||
|
@ -82,12 +82,12 @@ export class HuiGaugeCardEditor
|
|||||||
{
|
{
|
||||||
name: "min",
|
name: "min",
|
||||||
default: DEFAULT_MIN,
|
default: DEFAULT_MIN,
|
||||||
selector: { number: { mode: "box" } },
|
selector: { number: { mode: "box", step: "any" } },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "max",
|
name: "max",
|
||||||
default: DEFAULT_MAX,
|
default: DEFAULT_MAX,
|
||||||
selector: { number: { mode: "box" } },
|
selector: { number: { mode: "box", step: "any" } },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -107,15 +107,15 @@ export class HuiGaugeCardEditor
|
|||||||
schema: [
|
schema: [
|
||||||
{
|
{
|
||||||
name: "green",
|
name: "green",
|
||||||
selector: { number: { mode: "box" } },
|
selector: { number: { mode: "box", step: "any" } },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "yellow",
|
name: "yellow",
|
||||||
selector: { number: { mode: "box" } },
|
selector: { number: { mode: "box", step: "any" } },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "red",
|
name: "red",
|
||||||
selector: { number: { mode: "box" } },
|
selector: { number: { mode: "box", step: "any" } },
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
@ -2573,25 +2573,50 @@
|
|||||||
"label": "Call service",
|
"label": "Call service",
|
||||||
"response_variable": "Response variable",
|
"response_variable": "Response variable",
|
||||||
"has_optional_response": "This service can return a response, if you want to use the response, enter the name of a variable the response will be saved in",
|
"has_optional_response": "This service can return a response, if you want to use the response, enter the name of a variable the response will be saved in",
|
||||||
"has_response": "This service returns a response, enter the name of a variable the response will be saved in"
|
"has_response": "This service returns a response, enter the name of a variable the response will be saved in",
|
||||||
|
"description": {
|
||||||
|
"service_based_on_template": "Call a service based on a template on {targets}",
|
||||||
|
"service_based_on_name": "Call a service ''{name}'' on {targets}",
|
||||||
|
"service": "Call a service",
|
||||||
|
"target_template": "templated {name}",
|
||||||
|
"target_unknown_entity": "unknown entity",
|
||||||
|
"target_unknown_device": "unknown device",
|
||||||
|
"target_unknown_area": "unknown area"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"play_media": {
|
"play_media": {
|
||||||
"label": "Play media"
|
"label": "Play media",
|
||||||
|
"description": {
|
||||||
|
"full": "Play {hasMedia, select, \n true {{media}} \n other {media}\n } on {hasMediaPlayer, select, \n true {{mediaPlayer}} \n other {a media player}\n }"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"delay": {
|
"delay": {
|
||||||
"label": "Wait for time to pass (delay)",
|
"label": "Wait for time to pass (delay)",
|
||||||
"delay": "Duration"
|
"delay": "Duration",
|
||||||
|
"description": {
|
||||||
|
"full": "Delay {duration}",
|
||||||
|
"duration_string": "for {string}",
|
||||||
|
"duration_template": "based on a template",
|
||||||
|
"duration_unknown": "a duration"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"wait_template": {
|
"wait_template": {
|
||||||
"label": "Wait for a template",
|
"label": "Wait for a template",
|
||||||
"wait_template": "Wait Template",
|
"wait_template": "Wait Template",
|
||||||
"timeout": "Timeout (optional)",
|
"timeout": "Timeout (optional)",
|
||||||
"continue_timeout": "Continue on timeout"
|
"continue_timeout": "Continue on timeout",
|
||||||
|
"description": {
|
||||||
|
"full": "Wait for a template to evaluate to true"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"wait_for_trigger": {
|
"wait_for_trigger": {
|
||||||
"label": "Wait for a trigger",
|
"label": "Wait for a trigger",
|
||||||
"timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::timeout%]",
|
"timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::timeout%]",
|
||||||
"continue_timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::continue_timeout%]"
|
"continue_timeout": "[%key:ui::panel::config::automation::editor::actions::type::wait_template::continue_timeout%]",
|
||||||
|
"description": {
|
||||||
|
"wait_for_a_trigger": "Wait for a trigger",
|
||||||
|
"wait_for_triggers_with_name": "Wait for ''{triggers}''"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"condition": {
|
"condition": {
|
||||||
"label": "Condition"
|
"label": "Condition"
|
||||||
@ -2599,7 +2624,11 @@
|
|||||||
"event": {
|
"event": {
|
||||||
"label": "Event",
|
"label": "Event",
|
||||||
"event": "[%key:ui::panel::config::automation::editor::triggers::type::event::label%]",
|
"event": "[%key:ui::panel::config::automation::editor::triggers::type::event::label%]",
|
||||||
"event_data": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_data%]"
|
"event_data": "[%key:ui::panel::config::automation::editor::triggers::type::event::event_data%]",
|
||||||
|
"description": {
|
||||||
|
"full": "Fire event {name}",
|
||||||
|
"template": "based on a template"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"device_id": {
|
"device_id": {
|
||||||
"label": "Device",
|
"label": "Device",
|
||||||
@ -2618,7 +2647,11 @@
|
|||||||
},
|
},
|
||||||
"activate_scene": {
|
"activate_scene": {
|
||||||
"label": "Scene",
|
"label": "Scene",
|
||||||
"scene": "Scene"
|
"scene": "Scene",
|
||||||
|
"description": {
|
||||||
|
"activate_scene": "Activate a scene",
|
||||||
|
"activate_scene_with_name": "Activate scene {name}"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"repeat": {
|
"repeat": {
|
||||||
"label": "Repeat",
|
"label": "Repeat",
|
||||||
@ -2636,7 +2669,14 @@
|
|||||||
"conditions": "Until conditions"
|
"conditions": "Until conditions"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"sequence": "Actions"
|
"sequence": "Actions",
|
||||||
|
"description": {
|
||||||
|
"full": "Repeat an action {chosenAction}",
|
||||||
|
"count": "{count} {count, plural,\n one {time}\n other {times}\n}",
|
||||||
|
"while": "while ''{conditions}'' is true",
|
||||||
|
"until": "until ''{conditions}'' is true",
|
||||||
|
"for_each": "for every item: {items}"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"choose": {
|
"choose": {
|
||||||
"label": "Choose",
|
"label": "Choose",
|
||||||
@ -2646,26 +2686,47 @@
|
|||||||
"add_option": "Add option",
|
"add_option": "Add option",
|
||||||
"remove_option": "Remove option",
|
"remove_option": "Remove option",
|
||||||
"conditions": "Conditions",
|
"conditions": "Conditions",
|
||||||
"sequence": "Actions"
|
"sequence": "Actions",
|
||||||
|
"description": {
|
||||||
|
"full": "Choose between {number} {number, plural,\n one {action}\n other{actions}\n}",
|
||||||
|
"no_action": "Choose an action"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"if": {
|
"if": {
|
||||||
"label": "If-then",
|
"label": "If-then",
|
||||||
"if": "If",
|
"if": "If",
|
||||||
"then": "Then",
|
"then": "Then",
|
||||||
"else": "Else",
|
"else": "Else",
|
||||||
"add_else": "Add else"
|
"add_else": "Add else",
|
||||||
|
"description": {
|
||||||
|
"full": "Perform ''{action}'' if ''{conditions}''{hasElse, select, \n true { otherwise ''{elseAction}''} \n other {}\n } "
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"stop": {
|
"stop": {
|
||||||
"label": "Stop",
|
"label": "Stop",
|
||||||
"stop": "Reason for stopping",
|
"stop": "Reason for stopping",
|
||||||
"response_variable": "The name of the variable to use as response",
|
"response_variable": "The name of the variable to use as response",
|
||||||
"error": "Stop because of an unexpected error"
|
"error": "Stop because of an unexpected error",
|
||||||
|
"description": {
|
||||||
|
"full": "Stop {hasReason, select, \n true { because: {reason}} \n other {}\n }"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"parallel": {
|
"parallel": {
|
||||||
"label": "Run in parallel"
|
"label": "Run in parallel",
|
||||||
|
"description": {
|
||||||
|
"full": "Run {number} {number, plural,\n one {action}\n other {actions}\n} in parallel"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"variables": {
|
"variables": {
|
||||||
"label": "Define variables"
|
"label": "Define variables",
|
||||||
|
"description": {
|
||||||
|
"full": "Define variables {names}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"check_condition": {
|
||||||
|
"description": {
|
||||||
|
"full": "Test {condition}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2782,7 +2843,6 @@
|
|||||||
},
|
},
|
||||||
"discover_blueprint_tip": "[%key:ui::panel::config::automation::dialog_new::discover_blueprint_tip%]"
|
"discover_blueprint_tip": "[%key:ui::panel::config::automation::dialog_new::discover_blueprint_tip%]"
|
||||||
},
|
},
|
||||||
|
|
||||||
"editor": {
|
"editor": {
|
||||||
"alias": "Name",
|
"alias": "Name",
|
||||||
"icon": "Icon",
|
"icon": "Icon",
|
||||||
|
98
yarn.lock
98
yarn.lock
@ -2107,12 +2107,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@lrnwebcomponents/simple-tooltip@npm:7.0.10":
|
"@lrnwebcomponents/simple-tooltip@npm:7.0.11":
|
||||||
version: 7.0.10
|
version: 7.0.11
|
||||||
resolution: "@lrnwebcomponents/simple-tooltip@npm:7.0.10"
|
resolution: "@lrnwebcomponents/simple-tooltip@npm:7.0.11"
|
||||||
dependencies:
|
dependencies:
|
||||||
lit: ^2.7.5
|
lit: ^2.7.5
|
||||||
checksum: 4e355b580b21b246fed49d3625e6999777b12d8154b786ab27eeafba6d49d2efa4a49a8aa4e7b5e75874e68a1795f911f295f80eedeaf1ad5fbd633d6efeb7c4
|
checksum: 95c89d1f6ace6229b8661d953c792cef4d0842cbf4de830505a75f5fef9a312f730a7b0085aa11bb4e8e6c8a94d4c1d3512127d208695274f130e9f360f770b9
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -3141,14 +3141,14 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@material/web@npm:=1.0.0-pre.11":
|
"@material/web@npm:=1.0.0-pre.12":
|
||||||
version: 1.0.0-pre.11
|
version: 1.0.0-pre.12
|
||||||
resolution: "@material/web@npm:1.0.0-pre.11"
|
resolution: "@material/web@npm:1.0.0-pre.12"
|
||||||
dependencies:
|
dependencies:
|
||||||
lit: ^2.7.4
|
lit: ^2.7.4
|
||||||
safevalues: ^0.4.3
|
safevalues: ^0.4.3
|
||||||
tslib: ^2.4.0
|
tslib: ^2.4.0
|
||||||
checksum: 6c08d5d1b159472032d8a274eb29c22229dbcd29a80c478bbf680906903a9542dab9916d547e40c3b607a0ecfe51484bc8681b8c2f1fcd521b2b20fe23d84a66
|
checksum: 21132f90e004c84745bd9ba15aacc0ec74ee5c67e8dd610da14220cf0fa129882a82c409094b39226a82f9eaae0c1fbea9a6df07a6a056fc2ef5b771a14b078a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -9156,18 +9156,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"glob@npm:10.3.0, glob@npm:^10.2.2":
|
"glob@npm:10.3.1, glob@npm:^10.2.2":
|
||||||
version: 10.3.0
|
version: 10.3.1
|
||||||
resolution: "glob@npm:10.3.0"
|
resolution: "glob@npm:10.3.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: ^3.1.0
|
foreground-child: ^3.1.0
|
||||||
jackspeak: ^2.0.3
|
jackspeak: ^2.0.3
|
||||||
minimatch: ^9.0.1
|
minimatch: ^9.0.1
|
||||||
minipass: ^5.0.0 || ^6.0.2
|
minipass: ^5.0.0 || ^6.0.2
|
||||||
path-scurry: ^1.7.0
|
path-scurry: ^1.10.0
|
||||||
bin:
|
bin:
|
||||||
glob: dist/cjs/src/bin.js
|
glob: dist/cjs/src/bin.js
|
||||||
checksum: 6fa4ac0a86ffec1c5715a2e6fbdd63e1e7f1c2c8f5db08cc3256cdfcb81093678e7c80a3d100b502a1b9d141369ecf87bc24fe2bcb72acec7b14626d358a4eb0
|
checksum: 19c8c2805658b1002fecf0722cd609a33153d756a0d5260676bd0e9c5e6ef889ec9cce6d3dac0411aa90bce8de3d14f25b6f5589a3292582cccbfeddd0e98cc4
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -9578,10 +9578,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"hls.js@npm:1.4.6":
|
"hls.js@npm:1.4.7":
|
||||||
version: 1.4.6
|
version: 1.4.7
|
||||||
resolution: "hls.js@npm:1.4.6"
|
resolution: "hls.js@npm:1.4.7"
|
||||||
checksum: 7a44107c92e52859bfd5a37b6ea647cfea20848466286c1280b2cf956cfaccf8131fa54867cd8edfb60042a238025fb8788263fd9dfb9d1798ddbdc08f5aab50
|
checksum: ca58d97d49048fa6f437b834b807d26f5b47750aae57a573f179155e63e39159aa304f3ef13504b42c19969984918b17557e9311a779b0b04641bd6b668b45db
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -9622,7 +9622,7 @@ __metadata:
|
|||||||
"@lit-labs/context": 0.3.3
|
"@lit-labs/context": 0.3.3
|
||||||
"@lit-labs/motion": 1.0.3
|
"@lit-labs/motion": 1.0.3
|
||||||
"@lit-labs/virtualizer": 2.0.3
|
"@lit-labs/virtualizer": 2.0.3
|
||||||
"@lrnwebcomponents/simple-tooltip": 7.0.10
|
"@lrnwebcomponents/simple-tooltip": 7.0.11
|
||||||
"@material/chips": =14.0.0-canary.53b3cad2f.0
|
"@material/chips": =14.0.0-canary.53b3cad2f.0
|
||||||
"@material/data-table": =14.0.0-canary.53b3cad2f.0
|
"@material/data-table": =14.0.0-canary.53b3cad2f.0
|
||||||
"@material/mwc-button": 0.27.0
|
"@material/mwc-button": 0.27.0
|
||||||
@ -9648,7 +9648,7 @@ __metadata:
|
|||||||
"@material/mwc-top-app-bar": 0.27.0
|
"@material/mwc-top-app-bar": 0.27.0
|
||||||
"@material/mwc-top-app-bar-fixed": 0.27.0
|
"@material/mwc-top-app-bar-fixed": 0.27.0
|
||||||
"@material/top-app-bar": =14.0.0-canary.53b3cad2f.0
|
"@material/top-app-bar": =14.0.0-canary.53b3cad2f.0
|
||||||
"@material/web": =1.0.0-pre.11
|
"@material/web": =1.0.0-pre.12
|
||||||
"@mdi/js": 7.2.96
|
"@mdi/js": 7.2.96
|
||||||
"@mdi/svg": 7.2.96
|
"@mdi/svg": 7.2.96
|
||||||
"@octokit/auth-oauth-device": 5.0.2
|
"@octokit/auth-oauth-device": 5.0.2
|
||||||
@ -9728,7 +9728,7 @@ __metadata:
|
|||||||
fancy-log: 2.0.0
|
fancy-log: 2.0.0
|
||||||
fs-extra: 11.1.1
|
fs-extra: 11.1.1
|
||||||
fuse.js: 6.6.2
|
fuse.js: 6.6.2
|
||||||
glob: 10.3.0
|
glob: 10.3.1
|
||||||
google-timezones-json: 1.1.0
|
google-timezones-json: 1.1.0
|
||||||
gulp: 4.0.2
|
gulp: 4.0.2
|
||||||
gulp-flatmap: 1.0.2
|
gulp-flatmap: 1.0.2
|
||||||
@ -9736,7 +9736,7 @@ __metadata:
|
|||||||
gulp-merge-json: 2.1.2
|
gulp-merge-json: 2.1.2
|
||||||
gulp-rename: 2.0.0
|
gulp-rename: 2.0.0
|
||||||
gulp-zopfli-green: 6.0.1
|
gulp-zopfli-green: 6.0.1
|
||||||
hls.js: 1.4.6
|
hls.js: 1.4.7
|
||||||
home-assistant-js-websocket: 8.1.0
|
home-assistant-js-websocket: 8.1.0
|
||||||
html-minifier-terser: 7.2.0
|
html-minifier-terser: 7.2.0
|
||||||
husky: 8.0.3
|
husky: 8.0.3
|
||||||
@ -9747,7 +9747,7 @@ __metadata:
|
|||||||
jszip: 3.10.1
|
jszip: 3.10.1
|
||||||
leaflet: 1.9.4
|
leaflet: 1.9.4
|
||||||
leaflet-draw: 1.0.4
|
leaflet-draw: 1.0.4
|
||||||
lint-staged: 13.2.2
|
lint-staged: 13.2.3
|
||||||
lit: 2.7.5
|
lit: 2.7.5
|
||||||
lit-analyzer: 2.0.0-pre.3
|
lit-analyzer: 2.0.0-pre.3
|
||||||
lodash.template: 4.5.0
|
lodash.template: 4.5.0
|
||||||
@ -9785,7 +9785,7 @@ __metadata:
|
|||||||
ts-lit-plugin: 2.0.0-pre.1
|
ts-lit-plugin: 2.0.0-pre.1
|
||||||
tsparticles-engine: 2.10.1
|
tsparticles-engine: 2.10.1
|
||||||
tsparticles-preset-links: 2.10.1
|
tsparticles-preset-links: 2.10.1
|
||||||
typescript: 5.1.3
|
typescript: 5.1.6
|
||||||
unfetch: 5.0.0
|
unfetch: 5.0.0
|
||||||
vinyl-buffer: 1.0.1
|
vinyl-buffer: 1.0.1
|
||||||
vinyl-source-stream: 2.0.0
|
vinyl-source-stream: 2.0.0
|
||||||
@ -9793,7 +9793,7 @@ __metadata:
|
|||||||
vis-network: 9.1.6
|
vis-network: 9.1.6
|
||||||
vue: 2.7.14
|
vue: 2.7.14
|
||||||
vue2-daterange-picker: 0.6.8
|
vue2-daterange-picker: 0.6.8
|
||||||
webpack: 5.88.0
|
webpack: 5.88.1
|
||||||
webpack-cli: 5.1.4
|
webpack-cli: 5.1.4
|
||||||
webpack-dev-server: 4.15.1
|
webpack-dev-server: 4.15.1
|
||||||
webpack-manifest-plugin: 5.0.0
|
webpack-manifest-plugin: 5.0.0
|
||||||
@ -11309,9 +11309,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lint-staged@npm:13.2.2":
|
"lint-staged@npm:13.2.3":
|
||||||
version: 13.2.2
|
version: 13.2.3
|
||||||
resolution: "lint-staged@npm:13.2.2"
|
resolution: "lint-staged@npm:13.2.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
chalk: 5.2.0
|
chalk: 5.2.0
|
||||||
cli-truncate: ^3.1.0
|
cli-truncate: ^3.1.0
|
||||||
@ -11328,7 +11328,7 @@ __metadata:
|
|||||||
yaml: ^2.2.2
|
yaml: ^2.2.2
|
||||||
bin:
|
bin:
|
||||||
lint-staged: bin/lint-staged.js
|
lint-staged: bin/lint-staged.js
|
||||||
checksum: f34f6e2e85e827364658ab8717bf8b35239473c2d4959d746b053a4cf158ac657348444c755820a8ef3eac2d4753a37c52e9db3e201ee20b085f26d2f2fbc9ed
|
checksum: ff51a1e33072f488b28b938ed47323816a1ff278ef6d0e5cbe1704b292773a6c8ce945b504eae3a9b5702917a979523a741f17023e16077bd5fa35be687cc067
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -11622,10 +11622,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lru-cache@npm:^9.1.1":
|
"lru-cache@npm:^9.1.1 || ^10.0.0":
|
||||||
version: 9.1.2
|
version: 10.0.0
|
||||||
resolution: "lru-cache@npm:9.1.2"
|
resolution: "lru-cache@npm:10.0.0"
|
||||||
checksum: d3415634be3908909081fc4c56371a8d562d9081eba70543d86871b978702fffd0e9e362b83921b27a29ae2b37b90f55675aad770a54ac83bb3e4de5049d4b15
|
checksum: 18f101675fe283bc09cda0ef1e3cc83781aeb8373b439f086f758d1d91b28730950db785999cd060d3c825a8571c03073e8c14512b6655af2188d623031baf50
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -12954,13 +12954,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"path-scurry@npm:^1.7.0":
|
"path-scurry@npm:^1.10.0":
|
||||||
version: 1.9.2
|
version: 1.10.0
|
||||||
resolution: "path-scurry@npm:1.9.2"
|
resolution: "path-scurry@npm:1.10.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache: ^9.1.1
|
lru-cache: ^9.1.1 || ^10.0.0
|
||||||
minipass: ^5.0.0 || ^6.0.2
|
minipass: ^5.0.0 || ^6.0.2
|
||||||
checksum: 92888dfb68e285043c6d3291c8e971d5d2bc2f5082f4d7b5392896f34be47024c9d0a8b688dd7ae6d125acc424699195474927cb4f00049a9b1ec7c4256fa8e0
|
checksum: 3b66a4a6ab66e45755b577c966ecf0da92d3e068b3c992d8f69aa2cc908ef4eda9358253e9b4f86cad43d3ad810ec445be164105975f5cb3fdab68459c59dc6e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -15428,13 +15428,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@npm:5.1.3":
|
"typescript@npm:5.1.6":
|
||||||
version: 5.1.3
|
version: 5.1.6
|
||||||
resolution: "typescript@npm:5.1.3"
|
resolution: "typescript@npm:5.1.6"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
checksum: d9d51862d98efa46534f2800a1071a613751b1585dc78884807d0c179bcd93d6e9d4012a508e276742f5f33c480adefc52ffcafaf9e0e00ab641a14cde9a31c7
|
checksum: b2f2c35096035fe1f5facd1e38922ccb8558996331405eb00a5111cc948b2e733163cc22fab5db46992aba7dd520fff637f2c1df4996ff0e134e77d3249a7350
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -15448,13 +15448,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typescript@patch:typescript@5.1.3#~builtin<compat/typescript>":
|
"typescript@patch:typescript@5.1.6#~builtin<compat/typescript>":
|
||||||
version: 5.1.3
|
version: 5.1.6
|
||||||
resolution: "typescript@patch:typescript@npm%3A5.1.3#~builtin<compat/typescript>::version=5.1.3&hash=5da071"
|
resolution: "typescript@patch:typescript@npm%3A5.1.6#~builtin<compat/typescript>::version=5.1.6&hash=5da071"
|
||||||
bin:
|
bin:
|
||||||
tsc: bin/tsc
|
tsc: bin/tsc
|
||||||
tsserver: bin/tsserver
|
tsserver: bin/tsserver
|
||||||
checksum: 6f0a9dca6bf4ce9dcaf4e282aade55ef4c56ecb5fb98d0a4a5c0113398815aea66d871b5611e83353e5953a19ed9ef103cf5a76ac0f276d550d1e7cd5344f61e
|
checksum: f53bfe97f7c8b2b6d23cf572750d4e7d1e0c5fff1c36d859d0ec84556a827b8785077bc27676bf7e71fae538e517c3ecc0f37e7f593be913d884805d931bc8be
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -16135,9 +16135,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"webpack@npm:5.88.0":
|
"webpack@npm:5.88.1":
|
||||||
version: 5.88.0
|
version: 5.88.1
|
||||||
resolution: "webpack@npm:5.88.0"
|
resolution: "webpack@npm:5.88.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/eslint-scope": ^3.7.3
|
"@types/eslint-scope": ^3.7.3
|
||||||
"@types/estree": ^1.0.0
|
"@types/estree": ^1.0.0
|
||||||
@ -16168,7 +16168,7 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
bin:
|
bin:
|
||||||
webpack: bin/webpack.js
|
webpack: bin/webpack.js
|
||||||
checksum: 9fd1568b34ec2e99ba97c8509a15ab2576ec80c396e7015551ec814b24cfc11de173acba3e114dafe95f1a6d460781b09d6201e6a1fb15110e1d01a09f61a283
|
checksum: 726e7e05ab2e7c142609a673dd6aa1a711ed97f349418a2a393d650c5ddad172d191257f60e1e37f6b2a77261571c202aabd5ce9240791a686774f0801cf5ec2
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user