From 2bd6d9d202329fa446a38630732963b69d17b1c0 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 22 Feb 2023 12:20:45 +0100 Subject: [PATCH] Add group support to new more info light (#15543) --- src/data/group.ts | 11 +++++++ .../components/ha-more-info-toggle.ts | 31 ++++++++++++++----- src/dialogs/more-info/const.ts | 15 +++++++++ .../more-info/controls/more-info-group.ts | 18 +++++------ .../more-info/controls/more-info-light.ts | 3 +- src/dialogs/more-info/ha-more-info-dialog.ts | 4 +-- src/dialogs/more-info/ha-more-info-info.ts | 7 ++--- 7 files changed, 65 insertions(+), 24 deletions(-) diff --git a/src/data/group.ts b/src/data/group.ts index 3284358f31..cfae3ed858 100644 --- a/src/data/group.ts +++ b/src/data/group.ts @@ -2,6 +2,7 @@ import { HassEntityAttributeBase, HassEntityBase, } from "home-assistant-js-websocket"; +import { computeDomain } from "../common/entity/compute_domain"; interface GroupEntityAttributes extends HassEntityAttributeBase { entity_id: string[]; @@ -13,3 +14,13 @@ interface GroupEntityAttributes extends HassEntityAttributeBase { export interface GroupEntity extends HassEntityBase { attributes: GroupEntityAttributes; } + +export const computeGroupDomain = ( + stateObj: GroupEntity +): string | undefined => { + const entityIds = stateObj.attributes.entity_id || []; + const uniqueDomains = [ + ...new Set(entityIds.map((entityId) => computeDomain(entityId))), + ]; + return uniqueDomains.length === 1 ? uniqueDomains[0] : undefined; +}; diff --git a/src/dialogs/more-info/components/ha-more-info-toggle.ts b/src/dialogs/more-info/components/ha-more-info-toggle.ts index fabf68d407..a275ace41f 100644 --- a/src/dialogs/more-info/components/ha-more-info-toggle.ts +++ b/src/dialogs/more-info/components/ha-more-info-toggle.ts @@ -10,6 +10,7 @@ import { stateColorCss } from "../../../common/entity/state_color"; import "../../../components/ha-control-button"; import "../../../components/ha-control-switch"; import { UNAVAILABLE, UNKNOWN } from "../../../data/entity"; +import { forwardHaptic } from "../../../data/haptics"; import { HomeAssistant } from "../../../types"; @customElement("ha-more-info-toggle") @@ -33,16 +34,32 @@ export class HaMoreInfoToggle extends LitElement { } private _turnOn() { - const domain = computeDomain(this.stateObj!.entity_id); - this.hass.callService(domain, "turn_on", { - entity_id: this.stateObj!.entity_id, - }); + this._callService(true); } private _turnOff() { - const domain = computeDomain(this.stateObj!.entity_id); - this.hass.callService(domain, "turn_off", { - entity_id: this.stateObj!.entity_id, + this._callService(false); + } + + private async _callService(turnOn): Promise { + if (!this.hass || !this.stateObj) { + return; + } + forwardHaptic("light"); + const stateDomain = computeDomain(this.stateObj.entity_id); + let serviceDomain; + let service; + + if (stateDomain === "group") { + serviceDomain = "homeassistant"; + service = turnOn ? "turn_on" : "turn_off"; + } else { + serviceDomain = stateDomain; + service = turnOn ? "turn_on" : "turn_off"; + } + + await this.hass.callService(serviceDomain, service, { + entity_id: this.stateObj.entity_id, }); } diff --git a/src/dialogs/more-info/const.ts b/src/dialogs/more-info/const.ts index fde9c34c5f..3d36b61020 100644 --- a/src/dialogs/more-info/const.ts +++ b/src/dialogs/more-info/const.ts @@ -1,5 +1,7 @@ +import { HassEntity } from "home-assistant-js-websocket"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { computeDomain } from "../../common/entity/compute_domain"; +import { computeGroupDomain, GroupEntity } from "../../data/group"; import { CONTINUOUS_DOMAINS } from "../../data/logbook"; import { HomeAssistant } from "../../types"; @@ -89,3 +91,16 @@ export const computeShowLogBookComponent = ( return true; }; + +export const computeShowNewMoreInfo = (stateObj: HassEntity) => { + const domain = computeDomain(stateObj.entity_id); + if (domain === "group") { + const groupDomain = computeGroupDomain(stateObj as GroupEntity); + return ( + groupDomain && + groupDomain !== "group" && + DOMAINS_WITH_NEW_MORE_INFO.includes(groupDomain) + ); + } + return DOMAINS_WITH_NEW_MORE_INFO.includes(domain); +}; diff --git a/src/dialogs/more-info/controls/more-info-group.ts b/src/dialogs/more-info/controls/more-info-group.ts index c8b2e7bdbb..bc5536541d 100644 --- a/src/dialogs/more-info/controls/more-info-group.ts +++ b/src/dialogs/more-info/controls/more-info-group.ts @@ -9,8 +9,7 @@ import { } from "lit"; import { property, state } from "lit/decorators"; import { dynamicElement } from "../../../common/dom/dynamic-element-directive"; -import { computeStateDomain } from "../../../common/entity/compute_state_domain"; -import { GroupEntity } from "../../../data/group"; +import { computeGroupDomain, GroupEntity } from "../../../data/group"; import "../../../state-summary/state-card-content"; import { HomeAssistant } from "../../../types"; import { @@ -47,20 +46,19 @@ class MoreInfoGroup extends LitElement { } const baseStateObj = states.find((s) => s.state === "on") || states[0]; - const groupDomain = computeStateDomain(baseStateObj); + + const groupDomain = computeGroupDomain(this.stateObj); // Groups need to be filtered out or we'll show content of // first child above the children of the current group - if ( - groupDomain !== "group" && - states.every( - (entityState) => groupDomain === computeStateDomain(entityState) - ) - ) { + if (groupDomain && groupDomain !== "group") { this._groupDomainStateObj = { ...baseStateObj, entity_id: this.stateObj.entity_id, - attributes: { ...baseStateObj.attributes }, + attributes: { + ...baseStateObj.attributes, + friendly_name: this.stateObj.attributes.friendly_name, + }, }; const type = domainMoreInfoType(groupDomain); importMoreInfoControl(type); diff --git a/src/dialogs/more-info/controls/more-info-light.ts b/src/dialogs/more-info/controls/more-info-light.ts index 77e0a696ab..4500fc3f42 100644 --- a/src/dialogs/more-info/controls/more-info-light.ts +++ b/src/dialogs/more-info/controls/more-info-light.ts @@ -199,7 +199,8 @@ class MoreInfoLight extends LitElement { } private _toggle = () => { - this.hass.callService("light", "toggle", { + const service = this.stateObj?.state === "on" ? "turn_off" : "turn_on"; + this.hass.callService("light", service, { entity_id: this.stateObj!.entity_id, }); }; diff --git a/src/dialogs/more-info/ha-more-info-dialog.ts b/src/dialogs/more-info/ha-more-info-dialog.ts index 94a3942a2c..30beffa90b 100644 --- a/src/dialogs/more-info/ha-more-info-dialog.ts +++ b/src/dialogs/more-info/ha-more-info-dialog.ts @@ -32,7 +32,7 @@ import { HomeAssistant } from "../../types"; import { computeShowHistoryComponent, computeShowLogBookComponent, - DOMAINS_WITH_NEW_MORE_INFO, + computeShowNewMoreInfo, DOMAINS_WITH_MORE_INFO, EDITABLE_DOMAINS_WITH_ID, EDITABLE_DOMAINS_WITH_UNIQUE_ID, @@ -232,7 +232,7 @@ export class MoreInfoDialog extends LitElement { )} > `} - ${!isInfoView || !DOMAINS_WITH_NEW_MORE_INFO.includes(domain) + ${!isInfoView || !computeShowNewMoreInfo(stateObj) ? html`
` : ""} - ${DOMAINS_NO_INFO.includes(domain) || - DOMAINS_WITH_NEW_MORE_INFO.includes(domain) + ${DOMAINS_NO_INFO.includes(domain) || computeShowNewMoreInfo(stateObj) ? "" : html`