From 95dbc811d318e9331347639d0ab71cd7f68e96e1 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Fri, 3 Dec 2021 16:07:49 +0100 Subject: [PATCH] Allow overriding device class (#10777) --- src/data/entity_registry.ts | 3 + .../entities/entity-registry-settings.ts | 57 ++++++++++++++++++- src/translations/en.json | 14 +++++ 3 files changed, 71 insertions(+), 3 deletions(-) diff --git a/src/data/entity_registry.ts b/src/data/entity_registry.ts index becf455fc0..84fdbccec5 100644 --- a/src/data/entity_registry.ts +++ b/src/data/entity_registry.ts @@ -21,6 +21,8 @@ export interface ExtEntityRegistryEntry extends EntityRegistryEntry { capabilities: Record; original_name?: string; original_icon?: string; + device_class?: string; + original_device_class?: string; } export interface UpdateEntityRegistryEntryResult { @@ -32,6 +34,7 @@ export interface UpdateEntityRegistryEntryResult { export interface EntityRegistryEntryUpdateParams { name?: string | null; icon?: string | null; + device_class?: string | null; area_id?: string | null; disabled_by?: string | null; new_entity_id?: string; diff --git a/src/panels/config/entities/entity-registry-settings.ts b/src/panels/config/entities/entity-registry-settings.ts index 96fab20b01..0a489ae01a 100644 --- a/src/panels/config/entities/entity-registry-settings.ts +++ b/src/panels/config/entities/entity-registry-settings.ts @@ -1,5 +1,6 @@ import "@material/mwc-button/mwc-button"; import "@polymer/paper-input/paper-input"; +import type { PaperItemElement } from "@polymer/paper-item/paper-item"; import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, @@ -16,6 +17,7 @@ import { domainIcon } from "../../../common/entity/domain_icon"; import "../../../components/ha-area-picker"; import "../../../components/ha-expansion-panel"; import "../../../components/ha-icon-picker"; +import "../../../components/ha-paper-dropdown-menu"; import "../../../components/ha-switch"; import type { HaSwitch } from "../../../components/ha-switch"; import { @@ -39,6 +41,11 @@ import { haStyle } from "../../../resources/styles"; import type { HomeAssistant } from "../../../types"; import { showDeviceRegistryDetailDialog } from "../devices/device-registry-detail/show-dialog-device-registry-detail"; +const OVERRIDE_DEVICE_CLASSES = { + cover: ["window", "door", "garage"], + binary_sensor: ["window", "door", "garage_door", "opening"], +}; + @customElement("entity-registry-settings") export class EntityRegistrySettings extends SubscribeMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; @@ -51,6 +58,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { @state() private _entityId!: string; + @state() private _deviceClass?: string; + @state() private _areaId?: string | null; @state() private _disabledBy!: string | null; @@ -85,6 +94,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { this._error = undefined; this._name = this.entry.name || ""; this._icon = this.entry.icon || ""; + this._deviceClass = + this.entry.device_class || this.entry.original_device_class; this._origEntityId = this.entry.entity_id; this._areaId = this.entry.area_id; this._entityId = this.entry.entity_id; @@ -102,9 +113,11 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { } const stateObj: HassEntity | undefined = this.hass.states[this.entry.entity_id]; - const invalidDomainUpdate = - computeDomain(this._entityId.trim()) !== - computeDomain(this.entry.entity_id); + + const domain = computeDomain(this.entry.entity_id); + + const invalidDomainUpdate = computeDomain(this._entityId.trim()) !== domain; + return html` ${!stateObj ? html` @@ -143,6 +156,31 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { : undefined} .disabled=${this._submitting} > + ${OVERRIDE_DEVICE_CLASSES[domain]?.includes(this._deviceClass) || + (domain === "cover" && this.entry.original_device_class === null) + ? html` + + ${OVERRIDE_DEVICE_CLASSES[domain].map( + (deviceClass: string) => html` + + ${this.hass.localize( + `ui.dialogs.entity_registry.editor.device_classes.${domain}.${deviceClass}` + )} + + ` + )} + + ` + : ""} ): void { + this._error = undefined; + if (ev.detail.value === null) { + return; + } + const value = (ev.detail.value as any).itemValue; + this._deviceClass = value === "null" ? null : value; + } + private _areaPicked(ev: CustomEvent) { this._error = undefined; this._areaId = ev.detail.value; @@ -289,6 +336,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { name: this._name.trim() || null, icon: this._icon.trim() || null, area_id: this._areaId || null, + device_class: this._deviceClass || null, new_entity_id: this._entityId.trim(), }; if ( @@ -378,6 +426,9 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) { padding-bottom: max(env(safe-area-inset-bottom), 8px); background-color: var(--mdc-theme-surface, #fff); } + ha-paper-dropdown-menu { + width: 100%; + } ha-switch { margin-right: 16px; } diff --git a/src/translations/en.json b/src/translations/en.json index 4ee6773a57..bd2574bde1 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -694,6 +694,20 @@ "icon": "Icon", "icon_error": "Icons should be in the format 'prefix:iconname', e.g. 'mdi:home'", "entity_id": "Entity ID", + "device_class": "Show as", + "device_classes": { + "binary_sensor": { + "door": "Door", + "garage_door": "Garage door", + "window": "Window", + "opening": "Other" + }, + "cover": { + "door": "Door", + "garage": "Garage door", + "window": "Window" + } + }, "unavailable": "This entity is unavailable.", "enabled_label": "Enable entity", "enabled_cause": "Disabled by {cause}.",