Skip to content

Commit 910a336

Browse files
committed
feat(lock): add config option to show open door button when locked
closes #876
1 parent 80301c2 commit 910a336

File tree

7 files changed

+101
-62
lines changed

7 files changed

+101
-62
lines changed

docs/cards/lock.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@ A lock card allows you to control a lock entity.
1111

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

14-
| Name | Type | Default | Description |
15-
| :------------------ | :-------------------------------------------------- | :---------- | :---------------------------------------------------------------------------------- |
16-
| `entity` | string | Required | Lock entity |
17-
| `icon` | string | Optional | Custom icon |
18-
| `name` | string | Optional | Custom name |
19-
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported |
20-
| `fill_container` | boolean | `false` | Fill container or not. Useful when card is in a grid, vertical or horizontal layout |
21-
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
22-
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
23-
| `icon_type` | `icon` `entity-picture` `none` | `icon` | Type of icon to display |
24-
| `tap_action` | action | `more-info` | Home assistant action to perform on tap |
25-
| `hold_action` | action | `more-info` | Home assistant action to perform on hold |
26-
| `double_tap_action` | action | `more-info` | Home assistant action to perform on double_tap |
14+
| Name | Type | Default | Description |
15+
| :----------------------------- | :-------------------------------------------------- | :---------- | :---------------------------------------------------------------------------------------------------- |
16+
| `entity` | string | Required | Lock entity |
17+
| `icon` | string | Optional | Custom icon |
18+
| `name` | string | Optional | Custom name |
19+
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported |
20+
| `fill_container` | boolean | `false` | Fill container or not. Useful when card is in a grid, vertical or horizontal layout |
21+
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
22+
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
23+
| `icon_type` | `icon` `entity-picture` `none` | `icon` | Type of icon to display |
24+
| `tap_action` | action | `more-info` | Home assistant action to perform on tap |
25+
| `hold_action` | action | `more-info` | Home assistant action to perform on hold |
26+
| `double_tap_action` | action | `more-info` | Home assistant action to perform on double_tap |
27+
| `show_open_button_when_locked` | boolean | `false` | For compatible locks, the "Open" button is always available, whether your door is locked or unlocked. |
2728

2829
## Override theme variables
2930

src/cards/lock-card/controls/lock-buttons-control.ts

Lines changed: 55 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,35 +19,40 @@ interface LockButton {
1919
isDisabled: (entity: LockEntity) => boolean;
2020
}
2121

22-
export const LOCK_BUTTONS: LockButton[] = [
23-
{
24-
icon: "mdi:lock",
25-
title: "lock",
26-
serviceName: "lock",
27-
isVisible: (entity) => isUnlocked(entity),
28-
isDisabled: () => false,
29-
},
30-
{
31-
icon: "mdi:lock-open",
32-
title: "unlock",
33-
serviceName: "unlock",
34-
isVisible: (entity) => isLocked(entity),
35-
isDisabled: () => false,
36-
},
37-
{
38-
icon: "mdi:lock-clock",
39-
isVisible: (entity) => isActionPending(entity),
40-
isDisabled: () => true,
41-
},
42-
{
43-
icon: "mdi:door-open",
44-
title: "open",
45-
serviceName: "open",
46-
isVisible: (entity) =>
47-
supportsFeature(entity, LOCK_SUPPORT_OPEN) && isUnlocked(entity),
48-
isDisabled: (entity) => isActionPending(entity),
49-
},
50-
];
22+
export function getLockButtons(
23+
show_open_button_when_locked: boolean
24+
): LockButton[] {
25+
return [
26+
{
27+
icon: "mdi:lock",
28+
title: "lock",
29+
serviceName: "lock",
30+
isVisible: (entity) => isUnlocked(entity),
31+
isDisabled: () => false,
32+
},
33+
{
34+
icon: "mdi:lock-open",
35+
title: "unlock",
36+
serviceName: "unlock",
37+
isVisible: (entity) => isLocked(entity),
38+
isDisabled: () => false,
39+
},
40+
{
41+
icon: "mdi:lock-clock",
42+
isVisible: (entity) => isActionPending(entity),
43+
isDisabled: () => true,
44+
},
45+
{
46+
icon: "mdi:door-open",
47+
title: "open",
48+
serviceName: "open",
49+
isVisible: (entity) =>
50+
supportsFeature(entity, LOCK_SUPPORT_OPEN) &&
51+
(isUnlocked(entity) || show_open_button_when_locked),
52+
isDisabled: (entity) => isActionPending(entity),
53+
},
54+
];
55+
}
5156

5257
@customElement("mushroom-lock-buttons-control")
5358
export class LockButtonsControl extends LitElement {
@@ -57,6 +62,9 @@ export class LockButtonsControl extends LitElement {
5762

5863
@property({ type: Boolean }) public fill: boolean = false;
5964

65+
@property({ type: Boolean }) public show_open_button_when_locked: boolean =
66+
false;
67+
6068
private callService(e: CustomEvent) {
6169
e.stopPropagation();
6270
const entry = (e.target! as any).entry as LockButton;
@@ -70,22 +78,24 @@ export class LockButtonsControl extends LitElement {
7078
const customLocalize = setupCustomlocalize(this.hass!);
7179

7280
return html`
73-
<mushroom-button-group .fill=${this.fill} ?rtl=${rtl}
74-
>${LOCK_BUTTONS.filter((item) => item.isVisible(this.entity)).map(
75-
(item) => html`
76-
<mushroom-button
77-
.entry=${item}
78-
.title=${item.title
79-
? customLocalize(`editor.card.lock.${item.title}`)
80-
: ""}
81-
.disabled=${!isAvailable(this.entity) ||
82-
item.isDisabled(this.entity)}
83-
@click=${this.callService}
84-
>
85-
<ha-icon .icon=${item.icon}></ha-icon>
86-
</mushroom-button>
87-
`
88-
)}</mushroom-button-group
81+
<mushroom-button-group .fill=${this.fill} ?rtl=${rtl}>
82+
${getLockButtons(this.show_open_button_when_locked)
83+
.filter((item) => item.isVisible(this.entity))
84+
.map(
85+
(item) => html`
86+
<mushroom-button
87+
.entry=${item}
88+
.title=${item.title
89+
? customLocalize(`editor.card.lock.${item.title}`)
90+
: ""}
91+
.disabled=${!isAvailable(this.entity) ||
92+
item.isDisabled(this.entity)}
93+
@click=${this.callService}
94+
>
95+
<ha-icon .icon=${item.icon}></ha-icon>
96+
</mushroom-button>
97+
`
98+
)}</mushroom-button-group
8999
>
90100
`;
91101
}

src/cards/lock-card/lock-card-config.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ import { lovelaceCardConfigStruct } from "../../shared/config/lovelace-card-conf
1717
export type LockCardConfig = LovelaceCardConfig &
1818
EntitySharedConfig &
1919
AppearanceSharedConfig &
20-
ActionsSharedConfig;
20+
ActionsSharedConfig & {
21+
show_open_button_when_locked?: boolean;
22+
};
2123

2224
export const lockCardConfigStruct = assign(
2325
lovelaceCardConfigStruct,
2426
assign(
2527
entitySharedConfigStruct,
2628
appearanceSharedConfigStruct,
2729
actionsSharedConfigStruct
28-
)
30+
),
31+
object({
32+
show_open_button_when_locked: optional(boolean()),
33+
})
2934
);

src/cards/lock-card/lock-card-editor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ import { loadHaComponents } from "../../utils/loader";
1212
import { LOCK_CARD_EDITOR_NAME, LOCK_ENTITY_DOMAINS } from "./const";
1313
import { LockCardConfig, lockCardConfigStruct } from "./lock-card-config";
1414

15+
const LOCK_LABELS = ["show_open_button_when_locked"];
16+
1517
const SCHEMA: HaFormSchema[] = [
1618
{ name: "entity", selector: { entity: { domain: LOCK_ENTITY_DOMAINS } } },
1719
{ name: "name", selector: { text: {} } },
1820
{ name: "icon", selector: { icon: {} }, context: { icon_entity: "entity" } },
1921
...APPEARANCE_FORM_SCHEMA,
2022
...computeActionsFormSchema(),
23+
{ name: "show_open_button_when_locked", selector: { boolean: {} } },
2124
];
2225

2326
@customElement(LOCK_CARD_EDITOR_NAME)
@@ -43,6 +46,9 @@ export class LockCardEditor
4346
if (GENERIC_LABELS.includes(schema.name)) {
4447
return customLocalize(`editor.card.generic.${schema.name}`);
4548
}
49+
if (LOCK_LABELS.includes(schema.name)) {
50+
return customLocalize(`editor.card.lock.${schema.name}`);
51+
}
4652
return this.hass!.localize(
4753
`ui.panel.lovelace.editor.card.generic.${schema.name}`
4854
);

src/cards/lock-card/lock-card.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import {
3333
import "./controls/lock-buttons-control";
3434
import { LockCardConfig } from "./lock-card-config";
3535
import { isActionPending, isLocked, isUnlocked } from "./utils";
36+
import { FanCardConfig } from "../fan-card/fan-card-config";
3637

3738
registerCustomCard({
3839
type: LOCK_CARD_NAME,
@@ -67,6 +68,18 @@ export class LockCard
6768
return true;
6869
}
6970

71+
setConfig(config: FanCardConfig): void {
72+
super.setConfig({
73+
tap_action: {
74+
action: "toggle",
75+
},
76+
hold_action: {
77+
action: "more-info",
78+
},
79+
...config,
80+
});
81+
}
82+
7083
private _handleAction(ev: ActionHandlerEvent) {
7184
handleAction(this, this.hass!, this._config!, ev.detail.action!);
7285
}
@@ -114,6 +127,8 @@ export class LockCard
114127
.hass=${this.hass}
115128
.entity=${stateObj}
116129
.fill=${appearance.layout !== "horizontal"}
130+
.show_open_button_when_locked=${this._config
131+
.show_open_button_when_locked}
117132
>
118133
</mushroom-lock-buttons-control>
119134
</div>

src/translations/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@
131131
"lock": {
132132
"lock": "Lock",
133133
"unlock": "Unlock",
134-
"open": "Open"
134+
"open": "Open",
135+
"show_open_button_when_locked": "Show open button when locked?"
135136
},
136137
"humidifier": {
137138
"show_target_humidity_control": "Humidity control?"

src/translations/nl.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"lock": {
4747
"lock": "Vergrendel",
4848
"open": "Open",
49-
"unlock": "Ontgrendel"
49+
"unlock": "Ontgrendel",
50+
"show_open_button_when_locked": "Toon open-knop wanneer vergrendeld?"
5051
},
5152
"media-player": {
5253
"media_controls": "Mediabediening",

0 commit comments

Comments
 (0)