-
-
Notifications
You must be signed in to change notification settings - Fork 329
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat(card): lock * feat(lock): lock card * fix: missing hide state * fix: review * fix: review
- Loading branch information
Showing
15 changed files
with
511 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
title: Lock | ||
icon: mdi:lock | ||
cards: | ||
- type: grid | ||
title: Simple | ||
cards: | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
name: Custom name and icon | ||
icon: mdi:robot-outline | ||
columns: 2 | ||
square: false | ||
- type: grid | ||
title: Controls | ||
cards: | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
name: Buttons control | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
name: Position control | ||
columns: 2 | ||
square: false | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
name: Multiple controls | ||
- type: vertical-stack | ||
title: Layout | ||
cards: | ||
- type: grid | ||
columns: 2 | ||
square: false | ||
cards: | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
- type: grid | ||
columns: 2 | ||
square: false | ||
cards: | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
layout: "vertical" | ||
- type: custom:mushroom-lock-card | ||
entity: lock.front_door | ||
layout: "horizontal" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Lock card | ||
|
||
![Lock light](../images/lock-light.png) | ||
![Lock dark](../images/lock-dark.png) | ||
|
||
## Description | ||
|
||
A lock card allow you to control a lock entity. | ||
|
||
## Configuration variables | ||
|
||
All the options are available in the lovelace editor but you can use `yaml` if you want. | ||
|
||
| Name | Type | Default | Description | | ||
| :------------------ | :------ | :---------- | :------------------------------------------------------------------------ | | ||
| `entity` | string | Required | Lock entity | | ||
| `icon` | string | Optional | Custom icon | | ||
| `name` | string | Optional | Custom name | | ||
| `icon_color` | string | Optional | Custom icon color | | ||
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported | | ||
| `hide_state` | boolean | `false` | Hide the entity state | | ||
| `tap_action` | action | `more-info` | 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 | |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { PREFIX_NAME } from "../../const"; | ||
|
||
export const LOCK_CARD_NAME = `${PREFIX_NAME}-lock-card`; | ||
export const LOCK_CARD_EDITOR_NAME = `${LOCK_CARD_NAME}-editor`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { computeRTL, HomeAssistant } from "custom-card-helpers"; | ||
import { html, LitElement, TemplateResult } from "lit"; | ||
import { customElement, property } from "lit/decorators.js"; | ||
import { isAvailable } from "../../../ha/data/entity"; | ||
import { LockEntity } from "../../../ha/data/lock"; | ||
import { isActionPending, isLocked, isUnlocked } from "../utils"; | ||
|
||
interface LockButton { | ||
icon: string; | ||
serviceName?: string; | ||
isVisible: (entity: LockEntity) => boolean; | ||
isDisabled: (entity: LockEntity) => boolean; | ||
} | ||
|
||
export const LOCK_BUTTONS: LockButton[] = [ | ||
{ | ||
icon: "mdi:lock", | ||
serviceName: "lock", | ||
isVisible: (entity) => isUnlocked(entity), | ||
isDisabled: () => false, | ||
}, | ||
{ | ||
icon: "mdi:lock-open", | ||
serviceName: "unlock", | ||
isVisible: (entity) => isLocked(entity), | ||
isDisabled: () => false, | ||
}, | ||
{ | ||
icon: "mdi:lock-clock", | ||
isVisible: (entity) => isActionPending(entity), | ||
isDisabled: () => true, | ||
}, | ||
]; | ||
|
||
@customElement("mushroom-lock-buttons-control") | ||
export class LockButtonsControl extends LitElement { | ||
@property({ attribute: false }) public hass!: HomeAssistant; | ||
|
||
@property({ attribute: false }) public entity!: LockEntity; | ||
|
||
@property() public fill: boolean = false; | ||
|
||
private callService(e: CustomEvent) { | ||
e.stopPropagation(); | ||
const entry = (e.target! as any).entry as LockButton; | ||
this.hass.callService("lock", entry.serviceName!, { | ||
entity_id: this.entity!.entity_id, | ||
}); | ||
} | ||
|
||
protected render(): TemplateResult { | ||
const rtl = computeRTL(this.hass); | ||
|
||
return html` | ||
<mushroom-button-group .fill=${this.fill} .?rtl=${rtl} | ||
>${LOCK_BUTTONS.filter((item) => item.isVisible(this.entity)).map( | ||
(item) => html` | ||
<mushroom-button | ||
.icon=${item.icon} | ||
.entry=${item} | ||
.disabled=${!isAvailable(this.entity) || item.isDisabled(this.entity)} | ||
@click=${this.callService} | ||
></mushroom-button> | ||
` | ||
)}</mushroom-button-group | ||
> | ||
`; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { ActionConfig, LovelaceCardConfig } from "custom-card-helpers"; | ||
import { assign, boolean, object, optional, string } from "superstruct"; | ||
import { actionConfigStruct } from "../../utils/action-struct"; | ||
import { baseLovelaceCardConfig } from "../../utils/editor-styles"; | ||
import { Layout, layoutStruct } from "../../utils/layout"; | ||
|
||
export interface LockCardConfig extends LovelaceCardConfig { | ||
entity?: string; | ||
icon?: string; | ||
name?: string; | ||
icon_color?: string; | ||
layout?: Layout; | ||
hide_state?: boolean; | ||
tap_action?: ActionConfig; | ||
hold_action?: ActionConfig; | ||
double_tap_action?: ActionConfig; | ||
} | ||
|
||
export const lockCardConfigStruct = assign( | ||
baseLovelaceCardConfig, | ||
object({ | ||
entity: optional(string()), | ||
name: optional(string()), | ||
icon: optional(string()), | ||
icon_color: optional(string()), | ||
layout: optional(layoutStruct), | ||
hide_state: optional(boolean()), | ||
tap_action: optional(actionConfigStruct), | ||
hold_action: optional(actionConfigStruct), | ||
double_tap_action: optional(actionConfigStruct), | ||
}) | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { fireEvent, HomeAssistant, LovelaceCardEditor } from "custom-card-helpers"; | ||
import { CSSResultGroup, html, LitElement, TemplateResult } from "lit"; | ||
import { customElement, property, state } from "lit/decorators.js"; | ||
import memoizeOne from "memoize-one"; | ||
import { assert } from "superstruct"; | ||
import { LOCK_ENTITY_DOMAINS } from "../../ha/data/lock"; | ||
import setupCustomlocalize from "../../localize"; | ||
import { configElementStyle } from "../../utils/editor-styles"; | ||
import { GENERIC_FIELDS } from "../../utils/form/fields"; | ||
import { HaFormSchema } from "../../utils/form/ha-form"; | ||
import { stateIcon } from "../../utils/icons/state-icon"; | ||
import { loadHaComponents } from "../../utils/loader"; | ||
import { LOCK_CARD_EDITOR_NAME } from "./const"; | ||
import { LockCardConfig, lockCardConfigStruct } from "./lock-card-config"; | ||
|
||
const computeSchema = memoizeOne((icon?: string): HaFormSchema[] => [ | ||
{ name: "entity", selector: { entity: { domain : LOCK_ENTITY_DOMAINS} } }, | ||
{ name: "name", selector: { text: {} } }, | ||
{ | ||
type: "grid", | ||
name: "", | ||
schema: [ | ||
{ name: "icon", selector: { icon: { placeholder: icon } } }, | ||
{ name: "icon_color", selector: { "mush-color": {} } }, | ||
], | ||
}, | ||
{ | ||
type: "grid", | ||
name: "", | ||
schema: [ | ||
{ name: "layout", selector: { "mush-layout": {} } }, | ||
{ name: "hide_state", selector: { boolean: {} } }, | ||
], | ||
}, | ||
{ name: "tap_action", selector: { "mush-action": {} } }, | ||
{ name: "hold_action", selector: { "mush-action": {} } }, | ||
{ name: "double_tap_action", selector: { "mush-action": {} } }, | ||
]); | ||
|
||
@customElement(LOCK_CARD_EDITOR_NAME) | ||
export class LockCardEditor extends LitElement implements LovelaceCardEditor { | ||
@property({ attribute: false }) public hass?: HomeAssistant; | ||
|
||
@state() private _config?: LockCardConfig; | ||
|
||
connectedCallback() { | ||
super.connectedCallback(); | ||
void loadHaComponents(); | ||
} | ||
|
||
public setConfig(config: LockCardConfig): void { | ||
assert(config, lockCardConfigStruct); | ||
this._config = config; | ||
} | ||
|
||
private _computeLabelCallback = (schema: HaFormSchema) => { | ||
const customLocalize = setupCustomlocalize(this.hass!); | ||
|
||
if (GENERIC_FIELDS.includes(schema.name)) { | ||
return customLocalize(`editor.card.generic.${schema.name}`); | ||
} | ||
return this.hass!.localize(`ui.panel.lovelace.editor.card.generic.${schema.name}`); | ||
}; | ||
|
||
protected render(): TemplateResult { | ||
if (!this.hass || !this._config) { | ||
return html``; | ||
} | ||
|
||
const entityState = this._config.entity ? this.hass.states[this._config.entity] : undefined; | ||
const entityIcon = entityState ? stateIcon(entityState) : undefined; | ||
const icon = this._config.icon || entityIcon; | ||
const schema = computeSchema(icon); | ||
|
||
return html` | ||
<ha-form | ||
.hass=${this.hass} | ||
.data=${this._config} | ||
.schema=${schema} | ||
.computeLabel=${this._computeLabelCallback} | ||
@value-changed=${this._valueChanged} | ||
></ha-form> | ||
`; | ||
} | ||
|
||
private _valueChanged(ev: CustomEvent): void { | ||
fireEvent(this, "config-changed", { config: ev.detail.value }); | ||
} | ||
|
||
static get styles(): CSSResultGroup { | ||
return configElementStyle; | ||
} | ||
} |
Oops, something went wrong.