-
-
Notifications
You must be signed in to change notification settings - Fork 340
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(humidifier): add humidifier support (#346)
* feat(humidifier): card * feat(humidifier): improve card * fix: view name * fix: humidity live * fix: MushroomBaseElement * fix: clean unused dependencies * fix: hacard * fix: collapsible controls * fix: remove buttons control * fix: remove buttons control
- Loading branch information
Showing
18 changed files
with
520 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,6 +45,9 @@ fan: | |
|
||
lock: | ||
- platform: demo | ||
|
||
humidifier: | ||
- platform: demo | ||
|
||
person: | ||
- name: Anne Therese | ||
|
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,51 @@ | ||
title: Humidifier | ||
icon: mdi:air-humidifier | ||
cards: | ||
- type: grid | ||
title: Simple | ||
cards: | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
name: Custom name and icon | ||
icon: mdi:robot-outline | ||
columns: 2 | ||
square: false | ||
- type: grid | ||
title: Controls | ||
cards: | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
name: Humidity control | ||
show_target_humidity_control: true | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
name: Collapsible controls | ||
collapsible_controls: true | ||
show_target_humidity_control: true | ||
columns: 2 | ||
square: false | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
name: Multiple controls | ||
show_target_humidity_control: true | ||
- type: vertical-stack | ||
title: Layout | ||
cards: | ||
- type: grid | ||
columns: 2 | ||
square: false | ||
cards: | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
- type: grid | ||
columns: 2 | ||
square: false | ||
cards: | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
layout: "vertical" | ||
- type: custom:mushroom-humidifier-card | ||
entity: humidifier.humidifier | ||
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,26 @@ | ||
# Humidifier card | ||
|
||
![Humidifier light](../images/humidifier-light.png) | ||
![Humidifier dark](../images/humidifier-dark.png) | ||
|
||
## Description | ||
|
||
A humidifier card allow you to control a humidifier 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 | Humidifier entity | | ||
| `icon` | string | Optional | Custom icon | | ||
| `name` | string | Optional | Custom name | | ||
| `icon_color` | string | Optional | Custom icon color | | ||
| `fill_container` | boolean | `false` | Fill container or not. Useful when card is in a grid, vertical or horizontal layout | | ||
| `show_target_humidity_control` | boolean | Optional | Show target humidity control | | ||
| `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,5 @@ | ||
import { PREFIX_NAME } from "../../const"; | ||
|
||
export const HUMIDIFIER_CARD_NAME = `${PREFIX_NAME}-humidifier-card`; | ||
export const HUMIDIFIER_CARD_EDITOR_NAME = `${HUMIDIFIER_CARD_NAME}-editor`; | ||
export const HUMIDIFIER_ENTITY_DOMAINS = ["humidifier"]; |
64 changes: 64 additions & 0 deletions
64
src/cards/humidifier-card/controls/humidifier-humidity-control.ts
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,64 @@ | ||
import { HomeAssistant } from "custom-card-helpers"; | ||
import { html, LitElement, TemplateResult } from "lit"; | ||
import { customElement, property } from "lit/decorators.js"; | ||
import { styleMap } from "lit/directives/style-map.js"; | ||
import { isActive, isAvailable } from "../../../ha/data/entity"; | ||
import { HumidifierEntity } from "../../../ha/data/humidifier"; | ||
import "../../../shared/slider"; | ||
import { computeRgbColor } from "../../../utils/colors"; | ||
|
||
@customElement("mushroom-humidifier-humidity-control") | ||
export class HumidifierHumidityControl extends LitElement { | ||
@property({ attribute: false }) public hass!: HomeAssistant; | ||
|
||
@property({ attribute: false }) public entity!: HumidifierEntity; | ||
|
||
@property({ attribute: false }) public color!: string | undefined; | ||
|
||
onChange(e: CustomEvent<{ value: number }>): void { | ||
const value = e.detail.value; | ||
this.hass.callService("humidifier", "set_humidity", { | ||
entity_id: this.entity.entity_id, | ||
humidity: value, | ||
}); | ||
} | ||
|
||
onCurrentChange(e: CustomEvent<{ value?: number }>): void { | ||
const value = e.detail.value; | ||
this.dispatchEvent( | ||
new CustomEvent("current-change", { | ||
detail: { | ||
value, | ||
}, | ||
}) | ||
); | ||
} | ||
|
||
protected render(): TemplateResult { | ||
const max = this.entity.attributes.max_humidity || 100; | ||
const min = this.entity.attributes.min_humidity || 0; | ||
|
||
let sliderStyle = { | ||
"--main-color": "rgb(var(--rgb-state-humidifier));", | ||
"--bg-color": "rgba(var(--rgb-state-humidifier), 0.2);", | ||
}; | ||
|
||
if (this.color) { | ||
const rgbColor = computeRgbColor(this.color); | ||
sliderStyle["--main-color"] = `rgb(${rgbColor})`; | ||
sliderStyle["--bg-color"] = `rgba(${rgbColor}, 0.2)`; | ||
} | ||
|
||
return html`<mushroom-slider | ||
.value=${this.entity.attributes.humidity} | ||
.disabled=${!isAvailable(this.entity)} | ||
.inactive=${!isActive(this.entity)} | ||
.showActive=${true} | ||
.min=${min} | ||
.max=${max} | ||
@change=${this.onChange} | ||
style=${styleMap(sliderStyle)} | ||
@current-change=${this.onCurrentChange} | ||
/>`; | ||
} | ||
} |
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,36 @@ | ||
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 HumidifierCardConfig extends LovelaceCardConfig { | ||
entity?: string; | ||
icon?: string; | ||
icon_color?: string; | ||
name?: string; | ||
layout?: Layout; | ||
fill_container?: boolean; | ||
hide_state?: boolean; | ||
show_target_humidity_control?: boolean; | ||
tap_action?: ActionConfig; | ||
hold_action?: ActionConfig; | ||
double_tap_action?: ActionConfig; | ||
} | ||
|
||
export const humidifierCardConfigStruct = assign( | ||
baseLovelaceCardConfig, | ||
object({ | ||
entity: optional(string()), | ||
icon: optional(string()), | ||
icon_color: optional(string()), | ||
name: optional(string()), | ||
layout: optional(layoutStruct), | ||
fill_container: optional(boolean()), | ||
hide_state: optional(boolean()), | ||
show_target_humidity_control: 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,99 @@ | ||
import { fireEvent, LovelaceCardEditor } from "custom-card-helpers"; | ||
import { CSSResultGroup, html, TemplateResult } from "lit"; | ||
import { customElement, state } from "lit/decorators.js"; | ||
import memoizeOne from "memoize-one"; | ||
import { assert } from "superstruct"; | ||
import setupCustomlocalize from "../../localize"; | ||
import { MushroomBaseElement } from "../../utils/base-element"; | ||
import { GENERIC_LABELS } from "../../utils/form/generic-fields"; | ||
import { HaFormSchema } from "../../utils/form/ha-form"; | ||
import { stateIcon } from "../../utils/icons/state-icon"; | ||
import { loadHaComponents } from "../../utils/loader"; | ||
import { HUMIDIFIER_CARD_EDITOR_NAME, HUMIDIFIER_ENTITY_DOMAINS } from "./const"; | ||
import { HumidifierCardConfig, humidifierCardConfigStruct } from "./humidifier-card-config"; | ||
|
||
const HUMIDIFIER_FIELDS = ["show_target_humidity_control", "show_buttons_control"]; | ||
|
||
const computeSchema = memoizeOne((icon?: string): HaFormSchema[] => [ | ||
{ name: "entity", selector: { entity: { domain: HUMIDIFIER_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: "fill_container", selector: { boolean: {} } }, | ||
{ name: "hide_state", selector: { boolean: {} } }, | ||
], | ||
}, | ||
{ | ||
type: "grid", | ||
name: "", | ||
schema: [ | ||
{ name: "show_target_humidity_control", selector: { boolean: {} } }, | ||
], | ||
}, | ||
{ name: "tap_action", selector: { "mush-action": {} } }, | ||
{ name: "hold_action", selector: { "mush-action": {} } }, | ||
{ name: "double_tap_action", selector: { "mush-action": {} } }, | ||
]); | ||
|
||
@customElement(HUMIDIFIER_CARD_EDITOR_NAME) | ||
export class HumidifierCardEditor extends MushroomBaseElement implements LovelaceCardEditor { | ||
@state() private _config?: HumidifierCardConfig; | ||
|
||
connectedCallback() { | ||
super.connectedCallback(); | ||
void loadHaComponents(); | ||
} | ||
|
||
public setConfig(config: HumidifierCardConfig): void { | ||
assert(config, humidifierCardConfigStruct); | ||
this._config = config; | ||
} | ||
|
||
private _computeLabel = (schema: HaFormSchema) => { | ||
const customLocalize = setupCustomlocalize(this.hass!); | ||
|
||
if (GENERIC_LABELS.includes(schema.name)) { | ||
return customLocalize(`editor.card.generic.${schema.name}`); | ||
} | ||
if (HUMIDIFIER_FIELDS.includes(schema.name)) { | ||
return customLocalize(`editor.card.humidifier.${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._computeLabel} | ||
@value-changed=${this._valueChanged} | ||
></ha-form> | ||
`; | ||
} | ||
|
||
private _valueChanged(ev: CustomEvent): void { | ||
fireEvent(this, "config-changed", { config: ev.detail.value }); | ||
} | ||
} |
Oops, something went wrong.