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

feat(cover-card): allow custom actions for control buttons #1089

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
35 changes: 19 additions & 16 deletions docs/cards/cover.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,22 @@ A cover card allows you to control a cover entity.

All the options are available in the lovelace editor but you can use `yaml` if you want.

| Name | Type | Default | Description |
| :--------------------------- | :-------------------------------------------------- | :---------- | :---------------------------------------------------------------------------------- |
| `entity` | string | Required | Cover entity |
| `icon` | string | Optional | Custom icon |
| `name` | string | Optional | Custom name |
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported |
| `fill_container` | boolean | `false` | Fill container or not. Useful when card is in a grid, vertical or horizontal layout |
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
| `icon_type` | `icon` `entity-picture` `none` | `icon` | Type of icon to display |
| `show_buttons_control` | boolean | `false` | Show buttons to open, close and stop cover |
| `show_position_control` | boolean | `false` | Show a slider to control position of the cover |
| `show_tilt_position_control` | boolean | `false` | Show a slider to control tilt position of the cover |
| `tap_action` | action | `toggle` | Home assistant action to perform on tap |
| `hold_action` | action | `more-info` | Home assistant action to perform on hold |
| `double_tap_action` | action | `more-info` | Home assistant action to perform on double_tap |
| Name | Type | Default | Description |
|:-----------------------------|:----------------------------------------------------|:--------------|:------------------------------------------------------------------------------------|
| `entity` | string | Required | Cover entity |
| `icon` | string | Optional | Custom icon |
| `name` | string | Optional | Custom name |
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported |
| `fill_container` | boolean | `false` | Fill container or not. Useful when card is in a grid, vertical or horizontal layout |
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
| `icon_type` | `icon` `entity-picture` `none` | `icon` | Type of icon to display |
| `show_buttons_control` | boolean | `false` | Show buttons to open, close and stop cover |
| `show_position_control` | boolean | `false` | Show a slider to control position of the cover |
| `show_tilt_position_control` | boolean | `false` | Show a slider to control tilt position of the cover |
| `close_cover_action` | action | `Close cover` | Home assistant action to perform on tap on the close cover button |
| `stop_cover_action` | action | `Stop cover` | Home assistant action to perform on tap on the stop cover button |
| `open_cover_action` | action | `Open cover` | Home assistant action to perform on tap on the open cover button |
| `tap_action` | action | `toggle` | Home assistant action to perform on tap |
| `hold_action` | action | `more-info` | Home assistant action to perform on hold |
| `double_tap_action` | action | `more-info` | Home assistant action to perform on double_tap |
53 changes: 43 additions & 10 deletions src/cards/cover-card/controls/cover-buttons-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import {
computeRTL,
CoverEntity,
COVER_SUPPORT_CLOSE,
COVER_SUPPORT_OPEN,
COVER_SUPPORT_STOP,
CoverEntity,
HomeAssistant,
isAvailable,
isClosing,
Expand All @@ -17,6 +17,7 @@ import {
import "../../../shared/button";
import "../../../shared/button-group";
import { computeCloseIcon, computeOpenIcon } from "../../../utils/icons/cover-icon";
import {CoverCardConfig} from "../cover-card-config";

@customElement("mushroom-cover-buttons-control")
export class CoverButtonsControl extends LitElement {
Expand All @@ -26,25 +27,57 @@ export class CoverButtonsControl extends LitElement {

@property() public fill: boolean = false;

@property() public config!: CoverCardConfig;

private _onOpenTap(e: MouseEvent): void {
e.stopPropagation();
this.hass.callService("cover", "open_cover", {
entity_id: this.entity.entity_id,
});
if (this.config.open_cover_action) {
const [domain, service] = this.config.open_cover_action.service.split(".", 2);
this.hass.callService(
domain,
service,
this.config.open_cover_action.data ?? this.config.open_cover_action.service_data,
this.config?.open_cover_action.target
);
} else {
this.hass.callService("cover", "open_cover", {
entity_id: this.entity.entity_id,
});
}
}

private _onCloseTap(e: MouseEvent): void {
e.stopPropagation();
this.hass.callService("cover", "close_cover", {
entity_id: this.entity.entity_id,
});
if (this.config.close_cover_action) {
const [domain, service] = this.config.close_cover_action.service.split(".", 2);
this.hass.callService(
domain,
service,
this.config.close_cover_action.data ?? this.config.close_cover_action.service_data,
this.config.close_cover_action.target
);
} else {
this.hass.callService("cover", "close_cover", {
entity_id: this.entity.entity_id,
});
}
}

private _onStopTap(e: MouseEvent): void {
e.stopPropagation();
this.hass.callService("cover", "stop_cover", {
entity_id: this.entity.entity_id,
});
if (this.config.stop_cover_action) {
const [domain, service] = this.config.stop_cover_action.service.split(".", 2);
this.hass.callService(
domain,
service,
this.config.stop_cover_action.data ?? this.config.stop_cover_action.service_data,
this.config.stop_cover_action.target
);
} else {
this.hass.callService("cover", "stop_cover", {
entity_id: this.entity.entity_id,
});
}
}

private get openDisabled(): boolean {
Expand Down
11 changes: 9 additions & 2 deletions src/cards/cover-card/cover-card-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from "../../shared/config/appearance-config";
import { entitySharedConfigStruct, EntitySharedConfig } from "../../shared/config/entity-config";
import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-config";
import { LovelaceCardConfig } from "../../ha";
import { LovelaceCardConfig, actionConfigStruct, CallServiceActionConfig} from "../../ha";

export type CoverCardConfig = LovelaceCardConfig &
EntitySharedConfig &
Expand All @@ -15,7 +15,10 @@ export type CoverCardConfig = LovelaceCardConfig &
show_buttons_control?: false;
show_position_control?: false;
show_tilt_position_control?: false;
};
close_cover_action?: CallServiceActionConfig;
stop_cover_action?: CallServiceActionConfig;
open_cover_action?: CallServiceActionConfig;
};

export const coverCardConfigStruct = assign(
lovelaceCardConfigStruct,
Expand All @@ -24,5 +27,9 @@ export const coverCardConfigStruct = assign(
show_buttons_control: optional(boolean()),
show_position_control: optional(boolean()),
show_tilt_position_control: optional(boolean()),
close_cover_action: optional(actionConfigStruct),
stop_cover_action: optional(actionConfigStruct),
open_cover_action: optional(actionConfigStruct)
})
);

15 changes: 15 additions & 0 deletions src/cards/cover-card/cover-card-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ const COVER_LABELS = [
"show_buttons_control",
"show_position_control",
"show_tilt_position_control",
"close_cover_action",
"stop_cover_action",
"open_cover_action"
];

const computeSchema = memoizeOne((icon?: string): HaFormSchema[] => [
Expand All @@ -34,6 +37,18 @@ const computeSchema = memoizeOne((icon?: string): HaFormSchema[] => [
{ name: "show_buttons_control", selector: { boolean: {} } },
],
},
{
name: "close_cover_action",
selector: { "ui-action": {actions: ["call-service"] } },
},
{
name: "stop_cover_action",
selector: { "ui-action": {actions: ["call-service"] } },
},
{
name: "open_cover_action",
selector: { "ui-action": {actions: ["call-service"] } },
},
...computeActionsFormSchema(),
]);

Expand Down
1 change: 1 addition & 0 deletions src/cards/cover-card/cover-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ export class CoverCard extends MushroomBaseCard implements LovelaceCard {
.hass=${this.hass}
.entity=${entity}
.fill=${layout !== "horizontal"}
.config=${this._config}
/>
`;
case "position_control": {
Expand Down
5 changes: 4 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@
"cover": {
"show_buttons_control": "Control buttons?",
"show_position_control": "Position control?",
"show_tilt_position_control": "Tilt control?"
"show_tilt_position_control": "Tilt control?",
"close_cover_action": "Close Cover Action",
"stop_cover_action": "Stop Cover Action",
"open_cover_action": "Open Cover Action"
},
"alarm_control_panel": {
"show_keypad": "Show keypad"
Expand Down