diff --git a/gallery/src/pages/more-info/light.ts b/gallery/src/pages/more-info/light.ts index 999a4908ad..336aeb8ca8 100644 --- a/gallery/src/pages/more-info/light.ts +++ b/gallery/src/pages/more-info/light.ts @@ -1,12 +1,7 @@ import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, query } from "lit/decorators"; import "../../../../src/components/ha-card"; -import { - LightColorModes, - SUPPORT_EFFECT, - SUPPORT_FLASH, - SUPPORT_TRANSITION, -} from "../../../../src/data/light"; +import { LightColorMode, LightEntityFeature } from "../../../../src/data/light"; import "../../../../src/dialogs/more-info/more-info-content"; import { getEntity } from "../../../../src/fake_data/entity"; import { @@ -22,8 +17,8 @@ const ENTITIES = [ getEntity("light", "kitchen_light", "on", { friendly_name: "Brightness Light", brightness: 200, - supported_color_modes: [LightColorModes.BRIGHTNESS], - color_mode: LightColorModes.BRIGHTNESS, + supported_color_modes: [LightColorMode.BRIGHTNESS], + color_mode: LightColorMode.BRIGHTNESS, }), getEntity("light", "color_temperature_light", "on", { friendly_name: "White Color Temperature Light", @@ -32,10 +27,10 @@ const ENTITIES = [ min_mireds: 30, max_mireds: 150, supported_color_modes: [ - LightColorModes.BRIGHTNESS, - LightColorModes.COLOR_TEMP, + LightColorMode.BRIGHTNESS, + LightColorMode.COLOR_TEMP, ], - color_mode: LightColorModes.COLOR_TEMP, + color_mode: LightColorMode.COLOR_TEMP, }), getEntity("light", "color_hs_light", "on", { friendly_name: "Color HS Light", @@ -44,13 +39,16 @@ const ENTITIES = [ rgb_color: [30, 100, 255], min_mireds: 30, max_mireds: 150, - supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION, + supported_features: + LightEntityFeature.EFFECT + + LightEntityFeature.FLASH + + LightEntityFeature.TRANSITION, supported_color_modes: [ - LightColorModes.BRIGHTNESS, - LightColorModes.COLOR_TEMP, - LightColorModes.HS, + LightColorMode.BRIGHTNESS, + LightColorMode.COLOR_TEMP, + LightColorMode.HS, ], - color_mode: LightColorModes.HS, + color_mode: LightColorMode.HS, effect_list: ["random", "colorloop"], }), getEntity("light", "color_rgb_ct_light", "on", { @@ -59,22 +57,28 @@ const ENTITIES = [ color_temp: 75, min_mireds: 30, max_mireds: 150, - supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION, + supported_features: + LightEntityFeature.EFFECT + + LightEntityFeature.FLASH + + LightEntityFeature.TRANSITION, supported_color_modes: [ - LightColorModes.BRIGHTNESS, - LightColorModes.COLOR_TEMP, - LightColorModes.RGB, + LightColorMode.BRIGHTNESS, + LightColorMode.COLOR_TEMP, + LightColorMode.RGB, ], - color_mode: LightColorModes.COLOR_TEMP, + color_mode: LightColorMode.COLOR_TEMP, effect_list: ["random", "colorloop"], }), getEntity("light", "color_RGB_light", "on", { friendly_name: "Color Effects Light", brightness: 255, rgb_color: [30, 100, 255], - supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION, - supported_color_modes: [LightColorModes.BRIGHTNESS, LightColorModes.RGB], - color_mode: LightColorModes.RGB, + supported_features: + LightEntityFeature.EFFECT + + LightEntityFeature.FLASH + + LightEntityFeature.TRANSITION, + supported_color_modes: [LightColorMode.BRIGHTNESS, LightColorMode.RGB], + color_mode: LightColorMode.RGB, effect_list: ["random", "colorloop"], }), getEntity("light", "color_rgbw_light", "on", { @@ -83,13 +87,16 @@ const ENTITIES = [ rgbw_color: [30, 100, 255, 125], min_mireds: 30, max_mireds: 150, - supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION, + supported_features: + LightEntityFeature.EFFECT + + LightEntityFeature.FLASH + + LightEntityFeature.TRANSITION, supported_color_modes: [ - LightColorModes.BRIGHTNESS, - LightColorModes.COLOR_TEMP, - LightColorModes.RGBW, + LightColorMode.BRIGHTNESS, + LightColorMode.COLOR_TEMP, + LightColorMode.RGBW, ], - color_mode: LightColorModes.RGBW, + color_mode: LightColorMode.RGBW, effect_list: ["random", "colorloop"], }), getEntity("light", "color_rgbww_light", "on", { @@ -98,13 +105,16 @@ const ENTITIES = [ rgbww_color: [30, 100, 255, 125, 10], min_mireds: 30, max_mireds: 150, - supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION, + supported_features: + LightEntityFeature.EFFECT + + LightEntityFeature.FLASH + + LightEntityFeature.TRANSITION, supported_color_modes: [ - LightColorModes.BRIGHTNESS, - LightColorModes.COLOR_TEMP, - LightColorModes.RGBWW, + LightColorMode.BRIGHTNESS, + LightColorMode.COLOR_TEMP, + LightColorMode.RGBWW, ], - color_mode: LightColorModes.RGBWW, + color_mode: LightColorMode.RGBWW, effect_list: ["random", "colorloop"], }), getEntity("light", "color_xy_light", "on", { @@ -114,13 +124,16 @@ const ENTITIES = [ rgb_color: [30, 100, 255], min_mireds: 30, max_mireds: 150, - supported_features: SUPPORT_EFFECT + SUPPORT_FLASH + SUPPORT_TRANSITION, + supported_features: + LightEntityFeature.EFFECT + + LightEntityFeature.FLASH + + LightEntityFeature.TRANSITION, supported_color_modes: [ - LightColorModes.BRIGHTNESS, - LightColorModes.COLOR_TEMP, - LightColorModes.XY, + LightColorMode.BRIGHTNESS, + LightColorMode.COLOR_TEMP, + LightColorMode.XY, ], - color_mode: LightColorModes.XY, + color_mode: LightColorMode.XY, effect_list: ["random", "colorloop"], }), ]; diff --git a/src/data/light.ts b/src/data/light.ts index 93ae0c1d75..a171568451 100644 --- a/src/data/light.ts +++ b/src/data/light.ts @@ -3,76 +3,83 @@ import { HassEntityBase, } from "home-assistant-js-websocket"; -export const enum LightColorModes { +export const enum LightEntityFeature { + EFFECT = 4, + FLASH = 8, + TRANSITION = 32, +} + +export const enum LightColorMode { UNKNOWN = "unknown", ONOFF = "onoff", BRIGHTNESS = "brightness", COLOR_TEMP = "color_temp", - WHITE = "white", HS = "hs", XY = "xy", RGB = "rgb", RGBW = "rgbw", RGBWW = "rgbww", + WHITE = "white", } const modesSupportingColor = [ - LightColorModes.HS, - LightColorModes.XY, - LightColorModes.RGB, - LightColorModes.RGBW, - LightColorModes.RGBWW, + LightColorMode.HS, + LightColorMode.XY, + LightColorMode.RGB, + LightColorMode.RGBW, + LightColorMode.RGBWW, ]; -const modesSupportingDimming = [ +const modesSupportingBrightness = [ ...modesSupportingColor, - LightColorModes.COLOR_TEMP, - LightColorModes.BRIGHTNESS, + LightColorMode.COLOR_TEMP, + LightColorMode.BRIGHTNESS, + LightColorMode.WHITE, ]; -export const SUPPORT_EFFECT = 4; -export const SUPPORT_FLASH = 8; -export const SUPPORT_TRANSITION = 32; - export const lightSupportsColorMode = ( entity: LightEntity, - mode: LightColorModes -) => entity.attributes.supported_color_modes?.includes(mode); + mode: LightColorMode +) => entity.attributes.supported_color_modes?.includes(mode) || false; export const lightIsInColorMode = (entity: LightEntity) => - modesSupportingColor.includes(entity.attributes.color_mode); + (entity.attributes.color_mode && + modesSupportingColor.includes(entity.attributes.color_mode)) || + false; export const lightSupportsColor = (entity: LightEntity) => entity.attributes.supported_color_modes?.some((mode) => modesSupportingColor.includes(mode) ); -export const lightSupportsDimming = (entity: LightEntity) => +export const lightSupportsBrightness = (entity: LightEntity) => entity.attributes.supported_color_modes?.some((mode) => - modesSupportingDimming.includes(mode) - ); + modesSupportingBrightness.includes(mode) + ) || false; -export const getLightCurrentModeRgbColor = (entity: LightEntity): number[] => - entity.attributes.color_mode === LightColorModes.RGBWW +export const getLightCurrentModeRgbColor = ( + entity: LightEntity +): number[] | undefined => + entity.attributes.color_mode === LightColorMode.RGBWW ? entity.attributes.rgbww_color - : entity.attributes.color_mode === LightColorModes.RGBW + : entity.attributes.color_mode === LightColorMode.RGBW ? entity.attributes.rgbw_color : entity.attributes.rgb_color; interface LightEntityAttributes extends HassEntityAttributeBase { - min_mireds: number; - max_mireds: number; - friendly_name: string; - brightness: number; - hs_color: [number, number]; - rgb_color: [number, number, number]; - rgbw_color: [number, number, number, number]; - rgbww_color: [number, number, number, number, number]; - color_temp: number; + min_mireds?: number; + max_mireds?: number; + brightness?: number; + xy_color?: [number, number]; + hs_color?: [number, number]; + color_temp?: number; + rgb_color?: [number, number, number]; + rgbw_color?: [number, number, number, number]; + rgbww_color?: [number, number, number, number, number]; effect?: string; - effect_list: string[] | null; - supported_color_modes: LightColorModes[]; - color_mode: LightColorModes; + effect_list?: string[] | null; + supported_color_modes?: LightColorMode[]; + color_mode?: LightColorMode; } export interface LightEntity extends HassEntityBase { diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts index 29fb2644d8..be85eb7921 100644 --- a/src/dialogs/more-info/controls/more-info-light.ts +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -20,13 +20,13 @@ import "../../../components/ha-labeled-slider"; import "../../../components/ha-select"; import { getLightCurrentModeRgbColor, - LightColorModes, + LightColorMode, LightEntity, + LightEntityFeature, lightIsInColorMode, lightSupportsColor, lightSupportsColorMode, - lightSupportsDimming, - SUPPORT_EFFECT, + lightSupportsBrightness, } from "../../../data/light"; import type { HomeAssistant } from "../../../types"; @@ -56,7 +56,7 @@ class MoreInfoLight extends LitElement { @state() private _colorPickerColor?: [number, number, number]; - @state() private _mode?: "color" | LightColorModes; + @state() private _mode?: "color" | LightColorMode; protected render(): TemplateResult { if (!this.hass || !this.stateObj) { @@ -65,29 +65,29 @@ class MoreInfoLight extends LitElement { const supportsTemp = lightSupportsColorMode( this.stateObj, - LightColorModes.COLOR_TEMP + LightColorMode.COLOR_TEMP ); const supportsWhite = lightSupportsColorMode( this.stateObj, - LightColorModes.WHITE + LightColorMode.WHITE ); const supportsRgbww = lightSupportsColorMode( this.stateObj, - LightColorModes.RGBWW + LightColorMode.RGBWW ); const supportsRgbw = !supportsRgbww && - lightSupportsColorMode(this.stateObj, LightColorModes.RGBW); + lightSupportsColorMode(this.stateObj, LightColorMode.RGBW); const supportsColor = supportsRgbww || supportsRgbw || lightSupportsColor(this.stateObj); return html`
- ${lightSupportsDimming(this.stateObj) + ${lightSupportsBrightness(this.stateObj) ? html` @@ -260,31 +260,31 @@ class MoreInfoLight extends LitElement { let brightnessAdjust = 100; this._brightnessAdjusted = undefined; if ( - stateObj.attributes.color_mode === LightColorModes.RGB && - !lightSupportsColorMode(stateObj, LightColorModes.RGBWW) && - !lightSupportsColorMode(stateObj, LightColorModes.RGBW) + stateObj.attributes.color_mode === LightColorMode.RGB && + !lightSupportsColorMode(stateObj, LightColorMode.RGBWW) && + !lightSupportsColorMode(stateObj, LightColorMode.RGBW) ) { - const maxVal = Math.max(...stateObj.attributes.rgb_color); + const maxVal = Math.max(...stateObj.attributes.rgb_color!); if (maxVal < 255) { this._brightnessAdjusted = maxVal; brightnessAdjust = (this._brightnessAdjusted / 255) * 100; } } this._brightnessSliderValue = Math.round( - (stateObj.attributes.brightness * brightnessAdjust) / 255 + ((stateObj.attributes.brightness || 0) * brightnessAdjust) / 255 ); this._ctSliderValue = stateObj.attributes.color_temp; this._wvSliderValue = - stateObj.attributes.color_mode === LightColorModes.RGBW - ? Math.round((stateObj.attributes.rgbw_color[3] * 100) / 255) + stateObj.attributes.color_mode === LightColorMode.RGBW + ? Math.round((stateObj.attributes.rgbw_color![3] * 100) / 255) : undefined; this._cwSliderValue = - stateObj.attributes.color_mode === LightColorModes.RGBWW - ? Math.round((stateObj.attributes.rgbww_color[3] * 100) / 255) + stateObj.attributes.color_mode === LightColorMode.RGBWW + ? Math.round((stateObj.attributes.rgbww_color![3] * 100) / 255) : undefined; this._wwSliderValue = - stateObj.attributes.color_mode === LightColorModes.RGBWW - ? Math.round((stateObj.attributes.rgbww_color[4] * 100) / 255) + stateObj.attributes.color_mode === LightColorMode.RGBWW + ? Math.round((stateObj.attributes.rgbww_color![4] * 100) / 255) : undefined; const currentRgbColor = getLightCurrentModeRgbColor(stateObj); @@ -307,10 +307,10 @@ class MoreInfoLight extends LitElement { (supportsTemp: boolean, supportsWhite: boolean) => { const modes = [{ label: "Color", value: "color" }]; if (supportsTemp) { - modes.push({ label: "Temperature", value: LightColorModes.COLOR_TEMP }); + modes.push({ label: "Temperature", value: LightColorMode.COLOR_TEMP }); } if (supportsWhite) { - modes.push({ label: "White", value: LightColorModes.WHITE }); + modes.push({ label: "White", value: LightColorMode.WHITE }); } return modes; } @@ -342,7 +342,7 @@ class MoreInfoLight extends LitElement { this._brightnessSliderValue = bri; - if (this._mode === LightColorModes.WHITE) { + if (this._mode === LightColorMode.WHITE) { this.hass.callService("light", "turn_on", { entity_id: this.stateObj!.entity_id, white: Math.min(255, Math.round((bri * 255) / 100)), @@ -486,7 +486,7 @@ class MoreInfoLight extends LitElement { } private _setRgbWColor(rgbColor: [number, number, number]) { - if (lightSupportsColorMode(this.stateObj!, LightColorModes.RGBWW)) { + if (lightSupportsColorMode(this.stateObj!, LightColorMode.RGBWW)) { const rgbww_color: [number, number, number, number, number] = this .stateObj!.attributes.rgbww_color ? [...this.stateObj!.attributes.rgbww_color] @@ -495,7 +495,7 @@ class MoreInfoLight extends LitElement { entity_id: this.stateObj!.entity_id, rgbww_color: rgbColor.concat(rgbww_color.slice(3)), }); - } else if (lightSupportsColorMode(this.stateObj!, LightColorModes.RGBW)) { + } else if (lightSupportsColorMode(this.stateObj!, LightColorMode.RGBW)) { const rgbw_color: [number, number, number, number] = this.stateObj! .attributes.rgbw_color ? [...this.stateObj!.attributes.rgbw_color] @@ -524,8 +524,8 @@ class MoreInfoLight extends LitElement { ]; if ( - lightSupportsColorMode(this.stateObj!, LightColorModes.RGBWW) || - lightSupportsColorMode(this.stateObj!, LightColorModes.RGBW) + lightSupportsColorMode(this.stateObj!, LightColorMode.RGBWW) || + lightSupportsColorMode(this.stateObj!, LightColorMode.RGBW) ) { this._setRgbWColor( this._colorBrightnessSliderValue @@ -535,7 +535,7 @@ class MoreInfoLight extends LitElement { ) : [ev.detail.rgb.r, ev.detail.rgb.g, ev.detail.rgb.b] ); - } else if (lightSupportsColorMode(this.stateObj!, LightColorModes.RGB)) { + } else if (lightSupportsColorMode(this.stateObj!, LightColorMode.RGB)) { const rgb_color: [number, number, number] = [ ev.detail.rgb.r, ev.detail.rgb.g, diff --git a/src/panels/lovelace/cards/hui-light-card.ts b/src/panels/lovelace/cards/hui-light-card.ts index 595c299785..6717feef65 100644 --- a/src/panels/lovelace/cards/hui-light-card.ts +++ b/src/panels/lovelace/cards/hui-light-card.ts @@ -19,7 +19,7 @@ import "../../../components/ha-card"; import "../../../components/ha-icon-button"; import "../../../components/ha-state-icon"; import { UNAVAILABLE, UNAVAILABLE_STATES } from "../../../data/entity"; -import { LightEntity, lightSupportsDimming } from "../../../data/light"; +import { LightEntity, lightSupportsBrightness } from "../../../data/light"; import { ActionHandlerEvent } from "../../../data/lovelace"; import { HomeAssistant } from "../../../types"; import { actionHandler } from "../common/directives/action-handler-directive"; @@ -93,8 +93,9 @@ export class HuiLightCard extends LitElement implements LovelaceCard { `; } - const brightness = - Math.round((stateObj.attributes.brightness / 255) * 100) || 0; + const brightness = Math.round( + ((stateObj.attributes.brightness || 0) / 255) * 100 + ); const name = this._config.name ?? computeStateName(stateObj); @@ -121,14 +122,14 @@ export class HuiLightCard extends LitElement implements LovelaceCard { @value-changing=${this._dragEvent} @value-changed=${this._setBrightness} style=${styleMap({ - visibility: lightSupportsDimming(stateObj) + visibility: lightSupportsBrightness(stateObj) ? "visible" : "hidden", })} >