diff --git a/src/data/script.ts b/src/data/script.ts
index 5fdbbcfa46..81f8292f24 100644
--- a/src/data/script.ts
+++ b/src/data/script.ts
@@ -7,9 +7,15 @@ import { navigate } from "../common/navigate";
import { HomeAssistant } from "../types";
import { Condition } from "./automation";
+export const MODES = ["single", "restart", "queued", "parallel"];
+export const MODES_MAX = ["queued", "parallel"];
+
export interface ScriptEntity extends HassEntityBase {
attributes: HassEntityAttributeBase & {
last_triggered: string;
+ mode: "single" | "restart" | "queued" | "parallel";
+ current?: number;
+ max?: number;
};
}
@@ -66,6 +72,20 @@ export const triggerScript = (
variables?: {}
) => hass.callService("script", computeObjectId(entityId), variables);
+export const canExcecute = (state: ScriptEntity) => {
+ if (state.state === "off") {
+ return true;
+ }
+ if (
+ state.state === "on" &&
+ MODES_MAX.includes(state.attributes.mode) &&
+ state.attributes.current! < state.attributes.max!
+ ) {
+ return true;
+ }
+ return false;
+};
+
export const deleteScript = (hass: HomeAssistant, objectId: string) =>
hass.callApi("DELETE", `config/script/config/${objectId}`);
diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts
index be5422de69..68f334383a 100644
--- a/src/panels/config/script/ha-script-editor.ts
+++ b/src/panels/config/script/ha-script-editor.ts
@@ -22,6 +22,8 @@ import {
deleteScript,
getScriptEditorInitData,
ScriptConfig,
+ MODES,
+ MODES_MAX,
} from "../../../data/script";
import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box";
import "../../../layouts/ha-app-layout";
@@ -35,9 +37,6 @@ import "../../../components/ha-svg-icon";
import { mdiContentSave } from "@mdi/js";
import { PaperListboxElement } from "@polymer/paper-listbox";
-const MODES = ["single", "restart", "queued", "parallel"];
-const MODES_MAX = ["queued", "parallel"];
-
export class HaScriptEditor extends LitElement {
@property() public hass!: HomeAssistant;
diff --git a/src/panels/lovelace/entity-rows/hui-script-entity-row.ts b/src/panels/lovelace/entity-rows/hui-script-entity-row.ts
index 1105b6216e..06a49f68c1 100644
--- a/src/panels/lovelace/entity-rows/hui-script-entity-row.ts
+++ b/src/panels/lovelace/entity-rows/hui-script-entity-row.ts
@@ -9,17 +9,17 @@ import {
PropertyValues,
TemplateResult,
} from "lit-element";
-import "../../../components/entity/ha-entity-toggle";
import { UNAVAILABLE_STATES } from "../../../data/entity";
import { HomeAssistant } from "../../../types";
import { hasConfigOrEntityChanged } from "../common/has-changed";
import "../components/hui-generic-entity-row";
import { createEntityNotFoundWarning } from "../components/hui-warning";
import { ActionRowConfig, LovelaceRow } from "./types";
+import { canExcecute, ScriptEntity } from "../../../data/script";
@customElement("hui-script-entity-row")
class HuiScriptEntityRow extends LitElement implements LovelaceRow {
- public hass?: HomeAssistant;
+ @property() public hass?: HomeAssistant;
@property() private _config?: ActionRowConfig;
@@ -39,7 +39,7 @@ class HuiScriptEntityRow extends LitElement implements LovelaceRow {
return html``;
}
- const stateObj = this.hass.states[this._config.entity];
+ const stateObj = this.hass.states[this._config.entity] as ScriptEntity;
if (!stateObj) {
return html`
@@ -51,39 +51,51 @@ class HuiScriptEntityRow extends LitElement implements LovelaceRow {
return html`
- ${stateObj.attributes.can_cancel
- ? html`
-
- `
- : html`
-
- ${this._config.action_name ||
- this.hass!.localize("ui.card.script.execute")}
-
- `}
+ ${stateObj.state === "on"
+ ? html`
+ ${(stateObj.attributes.current || 0) > 0
+ ? this.hass.localize(
+ "ui.card.script.cancel_multiple",
+ "number",
+ stateObj.attributes.current
+ )
+ : this.hass.localize("ui.card.script.cancel")}
+ `
+ : ""}
+ ${stateObj.state === "off" || stateObj.attributes.max
+ ? html`
+ ${this._config.action_name ||
+ this.hass!.localize("ui.card.script.execute")}
+ `
+ : ""}
`;
}
static get styles(): CSSResult {
return css`
- mwc-button {
+ mwc-button:last-child {
margin-right: -0.57em;
}
`;
}
- private _callService(ev): void {
+ private _cancelScript(ev): void {
ev.stopPropagation();
- this.hass!.callService("script", "turn_on", {
+ this._callService("turn_off");
+ }
+
+ private _executeScript(ev): void {
+ ev.stopPropagation();
+ this._callService("turn_on");
+ }
+
+ private _callService(service: string): void {
+ this.hass!.callService("script", service, {
entity_id: this._config!.entity,
});
}
diff --git a/src/state-summary/state-card-script.js b/src/state-summary/state-card-script.js
deleted file mode 100644
index 462467b363..0000000000
--- a/src/state-summary/state-card-script.js
+++ /dev/null
@@ -1,74 +0,0 @@
-import "@material/mwc-button";
-import "@polymer/iron-flex-layout/iron-flex-layout-classes";
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
-import "../components/entity/ha-entity-toggle";
-import "../components/entity/state-info";
-import LocalizeMixin from "../mixins/localize-mixin";
-
-/*
- * @appliesMixin LocalizeMixin
- */
-class StateCardScript extends LocalizeMixin(PolymerElement) {
- static get template() {
- return html`
-
-
-
-
- ${this.stateInfoTemplate}
-
-
-
-
- [[localize('ui.card.script.execute')]]
-
-
- `;
- }
-
- static get stateInfoTemplate() {
- return html`
-
- `;
- }
-
- static get properties() {
- return {
- hass: Object,
- stateObj: Object,
- inDialog: {
- type: Boolean,
- value: false,
- },
- };
- }
-
- fireScript(ev) {
- ev.stopPropagation();
- this.hass.callService("script", "turn_on", {
- entity_id: this.stateObj.entity_id,
- });
- }
-}
-customElements.define("state-card-script", StateCardScript);
diff --git a/src/state-summary/state-card-script.ts b/src/state-summary/state-card-script.ts
new file mode 100644
index 0000000000..da04bff86a
--- /dev/null
+++ b/src/state-summary/state-card-script.ts
@@ -0,0 +1,77 @@
+import "@material/mwc-button";
+import "../components/entity/ha-entity-toggle";
+import "../components/entity/state-info";
+import { HomeAssistant } from "../types";
+import {
+ html,
+ customElement,
+ LitElement,
+ property,
+ CSSResult,
+} from "lit-element";
+import { HassEntity } from "home-assistant-js-websocket";
+import { haStyle } from "../resources/styles";
+import { UNAVAILABLE_STATES } from "../data/entity";
+import { canExcecute, ScriptEntity } from "../data/script";
+
+@customElement("state-card-script")
+export class StateCardScript extends LitElement {
+ @property() public hass!: HomeAssistant;
+
+ @property() public stateObj!: HassEntity;
+
+ @property({ type: Boolean }) public inDialog = false;
+
+ protected render() {
+ const stateObj = this.stateObj as ScriptEntity;
+ return html`
+
+
+ ${stateObj.state === "on"
+ ? html`
+ ${(stateObj.attributes.current || 0) > 0
+ ? this.hass.localize(
+ "ui.card.script.cancel_multiple",
+ "number",
+ stateObj.attributes.current
+ )
+ : this.hass.localize("ui.card.script.cancel")}
+ `
+ : ""}
+ ${stateObj.state === "off" || stateObj.attributes.max
+ ? html`
+ ${this.hass!.localize("ui.card.script.execute")}
+ `
+ : ""}
+
+ `;
+ }
+
+ private _cancelScript(ev: Event) {
+ ev.stopPropagation();
+ this._callService("turn_off");
+ }
+
+ private _executeScript(ev: Event) {
+ ev.stopPropagation();
+ this._callService("turn_on");
+ }
+
+ private _callService(service: string): void {
+ this.hass.callService("script", service, {
+ entity_id: this.stateObj.entity_id,
+ });
+ }
+
+ static get styles(): CSSResult {
+ return haStyle;
+ }
+}
diff --git a/src/translations/en.json b/src/translations/en.json
index c6fb6c4a17..9010307a42 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -188,7 +188,9 @@
"activate": "Activate"
},
"script": {
- "execute": "Execute"
+ "execute": "Execute",
+ "cancel": "Cancel",
+ "cancel_multiple": "Cancel {number}"
},
"service": {
"run": "Run"