Add set_conversation_response action (#19512)

This commit is contained in:
Bram Kragten 2024-01-23 13:16:49 +01:00 committed by GitHub
parent 88f67230fc
commit cc4cfe1b5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 85 additions and 109 deletions

View File

@ -13,14 +13,9 @@ import {
mdiClose,
mdiCodeBraces,
mdiCodeBrackets,
mdiDevices,
mdiGestureDoubleTap,
mdiHandBackRight,
mdiPalette,
mdiRefresh,
mdiRoomService,
mdiShuffleDisabled,
mdiTimerOutline,
} from "@mdi/js";
import { css, html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators";
@ -30,17 +25,14 @@ import { Condition, Trigger } from "../../data/automation";
import {
Action,
ChooseAction,
DelayAction,
DeviceAction,
EventAction,
IfAction,
ManualScriptConfig,
ParallelAction,
RepeatAction,
SceneAction,
ServiceAction,
WaitAction,
WaitForTriggerAction,
getActionType,
} from "../../data/script";
import {
ChooseActionTraceStep,
@ -53,6 +45,7 @@ import "./hat-graph-branch";
import { BRANCH_HEIGHT, NODE_SIZE, SPACING } from "./hat-graph-const";
import "./hat-graph-node";
import "./hat-graph-spacer";
import { ACTION_ICONS } from "../../data/action";
export interface NodeInfo {
path: string;
@ -115,17 +108,12 @@ export class HatScriptGraph extends LitElement {
and: this.render_condition_node,
or: this.render_condition_node,
not: this.render_condition_node,
delay: this.render_delay_node,
event: this.render_event_node,
scene: this.render_scene_node,
service: this.render_service_node,
wait_template: this.render_wait_node,
wait_for_trigger: this.render_wait_node,
repeat: this.render_repeat_node,
choose: this.render_choose_node,
device_id: this.render_device_node,
if: this.render_if_node,
stop: this.render_stop_node,
parallel: this.render_parallel_node,
other: this.render_other_node,
};
@ -371,63 +359,6 @@ export class HatScriptGraph extends LitElement {
`;
}
private render_delay_node(
node: DelayAction,
path: string,
graphStart = false,
disabled = false
) {
return html`
<hat-graph-node
.graphStart=${graphStart}
.iconPath=${mdiTimerOutline}
@focus=${this.selectNode(node, path)}
?track=${path in this.trace.trace}
?active=${this.selected === path}
.notEnabled=${disabled || node.enabled === false}
tabindex=${this.trace && path in this.trace.trace ? "0" : "-1"}
></hat-graph-node>
`;
}
private render_device_node(
node: DeviceAction,
path: string,
graphStart = false,
disabled = false
) {
return html`
<hat-graph-node
.graphStart=${graphStart}
.iconPath=${mdiDevices}
@focus=${this.selectNode(node, path)}
?track=${path in this.trace.trace}
?active=${this.selected === path}
.notEnabled=${disabled || node.enabled === false}
tabindex=${this.trace && path in this.trace.trace ? "0" : "-1"}
></hat-graph-node>
`;
}
private render_event_node(
node: EventAction,
path: string,
graphStart = false,
disabled = false
) {
return html`
<hat-graph-node
.graphStart=${graphStart}
.iconPath=${mdiGestureDoubleTap}
@focus=${this.selectNode(node, path)}
?track=${path in this.trace.trace}
?active=${this.selected === path}
.notEnabled=${disabled || node.enabled === false}
tabindex=${this.trace && path in this.trace.trace ? "0" : "-1"}
></hat-graph-node>
`;
}
private render_repeat_node(
node: RepeatAction,
path: string,
@ -475,25 +406,6 @@ export class HatScriptGraph extends LitElement {
`;
}
private render_scene_node(
node: SceneAction,
path: string,
graphStart = false,
disabled = false
) {
return html`
<hat-graph-node
.graphStart=${graphStart}
.iconPath=${mdiPalette}
@focus=${this.selectNode(node, path)}
?track=${path in this.trace.trace}
?active=${this.selected === path}
.notEnabled=${disabled || node.enabled === false}
tabindex=${this.trace && path in this.trace.trace ? "0" : "-1"}
></hat-graph-node>
`;
}
private render_service_node(
node: ServiceAction,
path: string,
@ -580,24 +492,6 @@ export class HatScriptGraph extends LitElement {
`;
}
private render_stop_node(
node: Action,
path: string,
graphStart = false,
disabled = false
) {
return html`
<hat-graph-node
.graphStart=${graphStart}
.iconPath=${mdiHandBackRight}
@focus=${this.selectNode(node, path)}
?track=${path in this.trace.trace}
?active=${this.selected === path}
.notEnabled=${disabled || node.enabled === false}
></hat-graph-node>
`;
}
private render_other_node(
node: Action,
path: string,
@ -607,7 +501,7 @@ export class HatScriptGraph extends LitElement {
return html`
<hat-graph-node
.graphStart=${graphStart}
.iconPath=${mdiCodeBrackets}
.iconPath=${ACTION_ICONS[getActionType(node)] || mdiCodeBrackets}
@focus=${this.selectNode(node, path)}
?track=${path in this.trace.trace}
?active=${this.selected === path}

View File

@ -2,6 +2,7 @@ import {
mdiAbTesting,
mdiApplicationVariableOutline,
mdiArrowDecision,
mdiBullhorn,
mdiCallSplit,
mdiCodeBraces,
mdiDevices,
@ -36,6 +37,7 @@ export const ACTION_ICONS = {
stop: mdiHandBackRight,
parallel: mdiShuffleDisabled,
variables: mdiApplicationVariableOutline,
set_conversation_response: mdiBullhorn,
} as const;
export const YAML_ONLY_ACTION_TYPES = new Set<keyof typeof ACTION_ICONS>([
@ -68,6 +70,7 @@ export const ACTION_GROUPS: AutomationElementGroup = {
members: {
event: {},
service: {},
set_conversation_response: {},
},
},
} as const;

View File

@ -248,6 +248,10 @@ export interface ParallelAction extends BaseAction {
parallel: ManualScriptConfig | Action | (ManualScriptConfig | Action)[];
}
export interface SetConversationResponseAction extends BaseAction {
set_conversation_response: string;
}
interface UnknownAction extends BaseAction {
[key: string]: unknown;
}
@ -292,6 +296,7 @@ export interface ActionTypes {
play_media: PlayMediaAction;
stop: StopAction;
parallel: ParallelAction;
set_conversation_response: SetConversationResponseAction;
unknown: UnknownAction;
}
@ -383,6 +388,9 @@ export const getActionType = (action: Action): ActionType => {
if ("parallel" in action) {
return "parallel";
}
if ("set_conversation_response" in action) {
return "set_conversation_response";
}
if ("service" in action) {
if ("metadata" in action) {
if (is(action, activateSceneActionStruct)) {

View File

@ -27,6 +27,7 @@ import {
PlayMediaAction,
RepeatAction,
SceneAction,
SetConversationResponseAction,
StopAction,
VariablesAction,
WaitForTriggerAction,
@ -443,5 +444,13 @@ const tryDescribeAction = <T extends ActionType>(
);
}
if (actionType === "set_conversation_response") {
const config = action as SetConversationResponseAction;
return hass.localize(
`${actionTranslationBaseKey}.set_conversation_response.description.full`,
{ response: config.set_conversation_response }
);
}
return actionType;
};

View File

@ -77,6 +77,7 @@ import "./types/ha-automation-action-service";
import "./types/ha-automation-action-stop";
import "./types/ha-automation-action-wait_for_trigger";
import "./types/ha-automation-action-wait_template";
import "./types/ha-automation-action-set_conversation_response";
export const getType = (action: Action | undefined) => {
if (!action) {

View File

@ -0,0 +1,54 @@
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import "../../../../../components/ha-form/ha-form";
import type { SetConversationResponseAction } from "../../../../../data/script";
import type { HomeAssistant } from "../../../../../types";
import type { ActionElement } from "../ha-automation-action-row";
const SCHEMA = [
{
name: "set_conversation_response",
selector: {
template: {},
},
},
] as const;
@customElement("ha-automation-action-set_conversation_response")
export class HaSetConversationResponseAction
extends LitElement
implements ActionElement
{
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public action!: SetConversationResponseAction;
@property({ type: Boolean }) public disabled = false;
public static get defaultConfig() {
return { set_conversation_response: "" };
}
protected render() {
return html`
<ha-form
.hass=${this.hass}
.data=${this.action}
.schema=${SCHEMA}
.disabled=${this.disabled}
.computeLabel=${this._computeLabelCallback}
></ha-form>
`;
}
private _computeLabelCallback = (): string =>
this.hass.localize(
"ui.panel.config.automation.editor.actions.type.set_conversation_response.label"
);
}
declare global {
interface HTMLElementTagNameMap {
"ha-automation-action-set_conversation_response": HaSetConversationResponseAction;
}
}

View File

@ -3117,6 +3117,13 @@
"full": "Test {condition}"
}
},
"set_conversation_response": {
"label": "Set conversation response",
"description": {
"picker": "Set response of conversation when automation was triggered by conversation trigger.",
"full": "Set response of conversation to {response}"
}
},
"unknown": {
"label": "Unknown"
}