Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Take convert of blueprint automation and script #21151

Merged
merged 6 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/data/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,22 @@ export const saveAutomationConfig = (
config: AutomationConfig
) => hass.callApi<void>("POST", `config/automation/config/${id}`, config);

export const normalizeAutomationConfig = <
T extends Partial<AutomationConfig> | AutomationConfig,
>(
config: T
): T => {
// Normalize data: ensure trigger, action and condition are lists
// Happens when people copy paste their automations into the config
for (const key of ["trigger", "condition", "action"]) {
const value = config[key];
if (value && !Array.isArray(value)) {
config[key] = [value];
}
}
return config;
};

export const showAutomationEditor = (data?: Partial<AutomationConfig>) => {
initialAutomationEditorData = data;
navigate("/config/automation/edit/new");
Expand Down
18 changes: 18 additions & 0 deletions src/data/blueprint.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HomeAssistant } from "../types";
import { ManualAutomationConfig } from "./automation";
import { Selector } from "./selector";

export type BlueprintDomain = "automation" | "script";
Expand Down Expand Up @@ -42,6 +43,10 @@ export interface BlueprintImportResult {
validation_errors: string[] | null;
}

export interface BlueprintSubstituteResult {
substituted_config: ManualAutomationConfig;
}

export const fetchBlueprints = (hass: HomeAssistant, domain: BlueprintDomain) =>
hass.callWS<Blueprints>({ type: "blueprint/list", domain });

Expand Down Expand Up @@ -91,3 +96,16 @@ export const getBlueprintSourceType = (
}
return "community";
};

export const substituteBlueprint = (
hass: HomeAssistant,
domain: BlueprintDomain,
path: string,
input: Record<string, any>
) =>
hass.callWS<BlueprintSubstituteResult>({
type: "blueprint/substitute",
domain,
path,
input,
});
3 changes: 2 additions & 1 deletion src/panels/config/automation/blueprint-automation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { HassEntity } from "home-assistant-js-websocket";
import { html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../components/ha-alert";
import "../../../components/ha-markdown";
piitaya marked this conversation as resolved.
Show resolved Hide resolved
import { BlueprintAutomationConfig } from "../../../data/automation";
import { fetchBlueprints } from "../../../data/blueprint";
import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor";
import "../../../components/ha-markdown";
import "./manual-automation-editor";

@customElement("blueprint-automation-editor")
export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor {
Expand Down
66 changes: 50 additions & 16 deletions src/panels/config/automation/ha-automation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
mdiDebugStepOver,
mdiDelete,
mdiDotsVertical,
mdiFileEdit,
piitaya marked this conversation as resolved.
Show resolved Hide resolved
mdiInformationOutline,
mdiPlay,
mdiPlayCircleOutline,
Expand Down Expand Up @@ -40,10 +41,12 @@ import "../../../components/ha-yaml-editor";
import {
AutomationConfig,
AutomationEntity,
BlueprintAutomationConfig,
deleteAutomation,
fetchAutomationFileConfig,
getAutomationEditorInitData,
getAutomationStateConfig,
normalizeAutomationConfig,
piitaya marked this conversation as resolved.
Show resolved Hide resolved
piitaya marked this conversation as resolved.
Show resolved Hide resolved
saveAutomationConfig,
showAutomationEditor,
triggerAutomationActions,
Expand All @@ -65,6 +68,7 @@ import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-a
import { showAutomationRenameDialog } from "./automation-rename-dialog/show-dialog-automation-rename";
import "./blueprint-automation-editor";
import "./manual-automation-editor";
import { substituteBlueprint } from "../../../data/blueprint";

declare global {
interface HTMLElementTagNameMap {
Expand Down Expand Up @@ -217,7 +221,21 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
></ha-svg-icon>
</ha-list-item>
`
: nothing}
: html`
<ha-list-item
graphic="icon"
@click=${this._takeControl}
.disabled=${this._readOnly || this._mode === "yaml"}
>
${this.hass.localize(
"ui.panel.config.automation.editor.take_control"
)}
<ha-svg-icon
slot="graphic"
.path=${mdiFileEdit}
></ha-svg-icon>
</ha-list-item>
`}

<ha-list-item
.disabled=${!this._readOnly && !this.automationId}
Expand Down Expand Up @@ -432,7 +450,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
}
this._config = {
...baseConfig,
...initData,
...(initData ? normalizeAutomationConfig(initData) : initData),
piitaya marked this conversation as resolved.
Show resolved Hide resolved
} as AutomationConfig;
this._entityId = undefined;
this._readOnly = false;
Expand All @@ -441,7 +459,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {

if (changedProps.has("entityId") && this.entityId) {
getAutomationStateConfig(this.hass, this.entityId).then((c) => {
this._config = this._normalizeConfig(c.config);
this._config = normalizeAutomationConfig(c.config);
this._checkValidation();
});
this._entityId = this.entityId;
Expand Down Expand Up @@ -497,18 +515,6 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
);
}

private _normalizeConfig(config: AutomationConfig): AutomationConfig {
// Normalize data: ensure trigger, action and condition are lists
// Happens when people copy paste their automations into the config
for (const key of ["trigger", "condition", "action"]) {
const value = config[key];
if (value && !Array.isArray(value)) {
config[key] = [value];
}
}
return config;
}

private async _loadConfig() {
try {
const config = await fetchAutomationFileConfig(
Expand All @@ -517,7 +523,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
);
this._dirty = false;
this._readOnly = false;
this._config = this._normalizeConfig(config);
this._config = normalizeAutomationConfig(config);
piitaya marked this conversation as resolved.
Show resolved Hide resolved
this._checkValidation();
} catch (err: any) {
const entityRegistry = await fetchEntityRegistry(this.hass.connection);
Expand Down Expand Up @@ -638,6 +644,34 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
}
};

private async _takeControl() {
const config = this._config as BlueprintAutomationConfig;

const confirmation = await showConfirmationDialog(this, {
title: "Take control of automation?",
text: "This automation is using a blueprint. By taking control, you will be able to edit it directly. Are you sure you want to take control?",
});

if (!confirmation) return;

const result = await substituteBlueprint(
this.hass,
"automation",
config.use_blueprint.path,
config.use_blueprint.input || {}
);

const newConfig = {
alias: config.alias,
description: config.description,
...normalizeAutomationConfig(result.substituted_config),
};

this._config = newConfig;
this._dirty = true;
this._errors = undefined;
}

private async _duplicate() {
const result = this._readOnly
? await showConfirmationDialog(this, {
Expand Down
1 change: 1 addition & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2759,6 +2759,7 @@
"unavailable": "Automation is unavailable",
"migrate": "Migrate",
"duplicate": "[%key:ui::common::duplicate%]",
"take_control": "Take control",
"run": "[%key:ui::panel::config::automation::editor::actions::run%]",
"rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]",
"show_trace": "Traces",
Expand Down
Loading