diff --git a/gallery/src/pages/more-info/cover.ts b/gallery/src/pages/more-info/cover.ts index 6afa1a6ff9..65f9ba4a25 100644 --- a/gallery/src/pages/more-info/cover.ts +++ b/gallery/src/pages/more-info/cover.ts @@ -1,16 +1,7 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; import "../../../../src/components/ha-card"; -import { - SUPPORT_OPEN, - SUPPORT_STOP, - SUPPORT_CLOSE, - SUPPORT_SET_POSITION, - SUPPORT_OPEN_TILT, - SUPPORT_STOP_TILT, - SUPPORT_CLOSE_TILT, - SUPPORT_SET_TILT_POSITION, -} from "../../../../src/data/cover"; +import { CoverEntityFeature } from "../../../../src/data/cover"; import "../../../../src/dialogs/more-info/more-info-content"; import { getEntity } from "../../../../src/fake_data/entity"; import { @@ -22,113 +13,127 @@ import "../../components/demo-more-infos"; const ENTITIES = [ getEntity("cover", "position_buttons", "on", { friendly_name: "Position Buttons", - supported_features: SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE, + supported_features: + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE, }), getEntity("cover", "position_slider_half", "on", { friendly_name: "Position Half-Open", supported_features: - SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE + SUPPORT_SET_POSITION, + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE + + CoverEntityFeature.SET_POSITION, current_position: 50, }), getEntity("cover", "position_slider_open", "on", { friendly_name: "Position Open", supported_features: - SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE + SUPPORT_SET_POSITION, + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE + + CoverEntityFeature.SET_POSITION, current_position: 100, }), getEntity("cover", "position_slider_closed", "on", { friendly_name: "Position Closed", supported_features: - SUPPORT_OPEN + SUPPORT_STOP + SUPPORT_CLOSE + SUPPORT_SET_POSITION, + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE + + CoverEntityFeature.SET_POSITION, current_position: 0, }), getEntity("cover", "tilt_buttons", "on", { friendly_name: "Tilt Buttons", supported_features: - SUPPORT_OPEN_TILT + SUPPORT_STOP_TILT + SUPPORT_CLOSE_TILT, + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT, }), getEntity("cover", "tilt_slider_half", "on", { friendly_name: "Tilt Half-Open", supported_features: - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT + - SUPPORT_SET_TILT_POSITION, + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT + + CoverEntityFeature.SET_TILT_POSITION, current_tilt_position: 50, }), getEntity("cover", "tilt_slider_open", "on", { friendly_name: "Tilt Open", supported_features: - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT + - SUPPORT_SET_TILT_POSITION, + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT + + CoverEntityFeature.SET_TILT_POSITION, current_tilt_position: 100, }), getEntity("cover", "tilt_slider_closed", "on", { friendly_name: "Tilt Closed", supported_features: - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT + - SUPPORT_SET_TILT_POSITION, + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT + + CoverEntityFeature.SET_TILT_POSITION, current_tilt_position: 0, }), getEntity("cover", "position_slider_tilt_slider", "on", { friendly_name: "Both Sliders", supported_features: - SUPPORT_OPEN + - SUPPORT_STOP + - SUPPORT_CLOSE + - SUPPORT_SET_POSITION + - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT + - SUPPORT_SET_TILT_POSITION, + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE + + CoverEntityFeature.SET_POSITION + + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT + + CoverEntityFeature.SET_TILT_POSITION, current_position: 30, current_tilt_position: 70, }), getEntity("cover", "position_tilt_slider", "on", { friendly_name: "Position & Tilt Slider", supported_features: - SUPPORT_OPEN + - SUPPORT_STOP + - SUPPORT_CLOSE + - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT + - SUPPORT_SET_TILT_POSITION, + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE + + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT + + CoverEntityFeature.SET_TILT_POSITION, current_tilt_position: 70, }), getEntity("cover", "position_slider_tilt", "on", { friendly_name: "Position Slider & Tilt", supported_features: - SUPPORT_OPEN + - SUPPORT_STOP + - SUPPORT_CLOSE + - SUPPORT_SET_POSITION + - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT, + CoverEntityFeature.OPEN + + CoverEntityFeature.STOP + + CoverEntityFeature.CLOSE + + CoverEntityFeature.SET_POSITION + + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT, current_position: 30, }), getEntity("cover", "position_slider_only_tilt_slider", "on", { friendly_name: "Position Slider Only & Tilt Buttons", supported_features: - SUPPORT_SET_POSITION + - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT, + CoverEntityFeature.SET_POSITION + + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT, current_position: 30, }), getEntity("cover", "position_slider_only_tilt", "on", { friendly_name: "Position Slider Only & Tilt", supported_features: - SUPPORT_SET_POSITION + - SUPPORT_OPEN_TILT + - SUPPORT_STOP_TILT + - SUPPORT_CLOSE_TILT + - SUPPORT_SET_TILT_POSITION, + CoverEntityFeature.SET_POSITION + + CoverEntityFeature.OPEN_TILT + + CoverEntityFeature.STOP_TILT + + CoverEntityFeature.CLOSE_TILT + + CoverEntityFeature.SET_TILT_POSITION, current_position: 30, current_tilt_position: 70, }), diff --git a/src/common/entity/feature_class_names.ts b/src/common/entity/feature_class_names.ts index aaa9220c28..7898e9d872 100644 --- a/src/common/entity/feature_class_names.ts +++ b/src/common/entity/feature_class_names.ts @@ -1,10 +1,14 @@ import { HassEntity } from "home-assistant-js-websocket"; import { supportsFeature } from "./supports-feature"; +export type FeatureClassNames = Partial< + Record +>; + // Expects classNames to be an object mapping feature-bit -> className export const featureClassNames = ( stateObj: HassEntity, - classNames: { [feature: number]: string } + classNames: FeatureClassNames ) => { if (!stateObj || !stateObj.attributes.supported_features) { return ""; diff --git a/src/components/ha-cover-controls.ts b/src/components/ha-cover-controls.ts index 73a1acbc5d..95b93ac039 100644 --- a/src/components/ha-cover-controls.ts +++ b/src/components/ha-cover-controls.ts @@ -3,15 +3,14 @@ import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; import { computeCloseIcon, computeOpenIcon } from "../common/entity/cover_icon"; +import { supportsFeature } from "../common/entity/supports-feature"; import { CoverEntity, + CoverEntityFeature, isClosing, isFullyClosed, isFullyOpen, isOpening, - supportsClose, - supportsOpen, - supportsStop, } from "../data/cover"; import { UNAVAILABLE } from "../data/entity"; import type { HomeAssistant } from "../types"; @@ -32,7 +31,7 @@ class HaCoverControls extends LitElement {
- supportsFeature(stateObj, SUPPORT_OPEN); - -export const supportsClose = (stateObj) => - supportsFeature(stateObj, SUPPORT_CLOSE); - -export const supportsSetPosition = (stateObj) => - supportsFeature(stateObj, SUPPORT_SET_POSITION); - -export const supportsStop = (stateObj) => - supportsFeature(stateObj, SUPPORT_STOP); - -export const supportsOpenTilt = (stateObj) => - supportsFeature(stateObj, SUPPORT_OPEN_TILT); - -export const supportsCloseTilt = (stateObj) => - supportsFeature(stateObj, SUPPORT_CLOSE_TILT); - -export const supportsStopTilt = (stateObj) => - supportsFeature(stateObj, SUPPORT_STOP_TILT); - -export const supportsSetTiltPosition = (stateObj) => - supportsFeature(stateObj, SUPPORT_SET_TILT_POSITION); +export const enum CoverEntityFeature { + OPEN = 1, + CLOSE = 2, + SET_POSITION = 4, + STOP = 8, + OPEN_TILT = 16, + CLOSE_TILT = 32, + STOP_TILT = 64, + SET_TILT_POSITION = 128, +} export function isFullyOpen(stateObj: CoverEntity) { if (stateObj.attributes.current_position !== undefined) { @@ -77,17 +47,19 @@ export function isClosing(stateObj: CoverEntity) { export function isTiltOnly(stateObj: CoverEntity) { const supportsCover = - supportsOpen(stateObj) || supportsClose(stateObj) || supportsStop(stateObj); + supportsFeature(stateObj, CoverEntityFeature.OPEN) || + supportsFeature(stateObj, CoverEntityFeature.CLOSE) || + supportsFeature(stateObj, CoverEntityFeature.STOP); const supportsTilt = - supportsOpenTilt(stateObj) || - supportsCloseTilt(stateObj) || - supportsStopTilt(stateObj); + supportsFeature(stateObj, CoverEntityFeature.OPEN_TILT) || + supportsFeature(stateObj, CoverEntityFeature.CLOSE_TILT) || + supportsFeature(stateObj, CoverEntityFeature.STOP_TILT); return supportsTilt && !supportsCover; } interface CoverEntityAttributes extends HassEntityAttributeBase { - current_position: number; - current_tilt_position: number; + current_position?: number; + current_tilt_position?: number; } export interface CoverEntity extends HassEntityBase { diff --git a/src/dialogs/more-info/controls/more-info-cover.ts b/src/dialogs/more-info/controls/more-info-cover.ts index 61faf09af2..6f6125578b 100644 --- a/src/dialogs/more-info/controls/more-info-cover.ts +++ b/src/dialogs/more-info/controls/more-info-cover.ts @@ -1,19 +1,29 @@ import { css, CSSResult, html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; import { attributeClassNames } from "../../../common/entity/attribute_class_names"; -import { featureClassNames } from "../../../common/entity/feature_class_names"; +import { + FeatureClassNames, + featureClassNames, +} from "../../../common/entity/feature_class_names"; +import { supportsFeature } from "../../../common/entity/supports-feature"; import "../../../components/ha-attributes"; import "../../../components/ha-cover-tilt-controls"; import "../../../components/ha-labeled-slider"; import { CoverEntity, - FEATURE_CLASS_NAMES, + CoverEntityFeature, isTiltOnly, - supportsSetPosition, - supportsSetTiltPosition, } from "../../../data/cover"; import { HomeAssistant } from "../../../types"; +export const FEATURE_CLASS_NAMES: FeatureClassNames = { + [CoverEntityFeature.SET_POSITION]: "has-set_position", + [CoverEntityFeature.OPEN_TILT]: "has-open_tilt", + [CoverEntityFeature.CLOSE_TILT]: "has-close_tilt", + [CoverEntityFeature.STOP_TILT]: "has-stop_tilt", + [CoverEntityFeature.SET_TILT_POSITION]: "has-set_tilt_position", +}; + @customElement("more-info-cover") class MoreInfoCover extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -34,13 +44,16 @@ class MoreInfoCover extends LitElement { .caption=${this.hass.localize("ui.card.cover.position")} pin="" .value=${this.stateObj.attributes.current_position} - .disabled=${!supportsSetPosition(this.stateObj)} + .disabled=${!supportsFeature( + this.stateObj, + CoverEntityFeature.SET_POSITION + )} @change=${this._coverPositionSliderChanged} >
- ${supportsSetTiltPosition(this.stateObj) + ${supportsFeature(this.stateObj, CoverEntityFeature.SET_TILT_POSITION) ? // Either render the labeled slider and put the tilt buttons into its slot // or (if tilt position is not supported and therefore no slider is shown) // render a title
(same style as for a labeled slider) and directly put