Allow overriding device class (#10777)

This commit is contained in:
Bram Kragten 2021-12-03 16:07:49 +01:00 committed by GitHub
parent e28a11964e
commit 95dbc811d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 3 deletions

View File

@ -21,6 +21,8 @@ export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
capabilities: Record<string, unknown>; capabilities: Record<string, unknown>;
original_name?: string; original_name?: string;
original_icon?: string; original_icon?: string;
device_class?: string;
original_device_class?: string;
} }
export interface UpdateEntityRegistryEntryResult { export interface UpdateEntityRegistryEntryResult {
@ -32,6 +34,7 @@ export interface UpdateEntityRegistryEntryResult {
export interface EntityRegistryEntryUpdateParams { export interface EntityRegistryEntryUpdateParams {
name?: string | null; name?: string | null;
icon?: string | null; icon?: string | null;
device_class?: string | null;
area_id?: string | null; area_id?: string | null;
disabled_by?: string | null; disabled_by?: string | null;
new_entity_id?: string; new_entity_id?: string;

View File

@ -1,5 +1,6 @@
import "@material/mwc-button/mwc-button"; import "@material/mwc-button/mwc-button";
import "@polymer/paper-input/paper-input"; import "@polymer/paper-input/paper-input";
import type { PaperItemElement } from "@polymer/paper-item/paper-item";
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
import { import {
css, css,
@ -16,6 +17,7 @@ import { domainIcon } from "../../../common/entity/domain_icon";
import "../../../components/ha-area-picker"; import "../../../components/ha-area-picker";
import "../../../components/ha-expansion-panel"; import "../../../components/ha-expansion-panel";
import "../../../components/ha-icon-picker"; import "../../../components/ha-icon-picker";
import "../../../components/ha-paper-dropdown-menu";
import "../../../components/ha-switch"; import "../../../components/ha-switch";
import type { HaSwitch } from "../../../components/ha-switch"; import type { HaSwitch } from "../../../components/ha-switch";
import { import {
@ -39,6 +41,11 @@ import { haStyle } from "../../../resources/styles";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { showDeviceRegistryDetailDialog } from "../devices/device-registry-detail/show-dialog-device-registry-detail"; 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") @customElement("entity-registry-settings")
export class EntityRegistrySettings extends SubscribeMixin(LitElement) { export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@ -51,6 +58,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
@state() private _entityId!: string; @state() private _entityId!: string;
@state() private _deviceClass?: string;
@state() private _areaId?: string | null; @state() private _areaId?: string | null;
@state() private _disabledBy!: string | null; @state() private _disabledBy!: string | null;
@ -85,6 +94,8 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
this._error = undefined; this._error = undefined;
this._name = this.entry.name || ""; this._name = this.entry.name || "";
this._icon = this.entry.icon || ""; this._icon = this.entry.icon || "";
this._deviceClass =
this.entry.device_class || this.entry.original_device_class;
this._origEntityId = this.entry.entity_id; this._origEntityId = this.entry.entity_id;
this._areaId = this.entry.area_id; this._areaId = this.entry.area_id;
this._entityId = this.entry.entity_id; this._entityId = this.entry.entity_id;
@ -102,9 +113,11 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
} }
const stateObj: HassEntity | undefined = const stateObj: HassEntity | undefined =
this.hass.states[this.entry.entity_id]; this.hass.states[this.entry.entity_id];
const invalidDomainUpdate =
computeDomain(this._entityId.trim()) !== const domain = computeDomain(this.entry.entity_id);
computeDomain(this.entry.entity_id);
const invalidDomainUpdate = computeDomain(this._entityId.trim()) !== domain;
return html` return html`
${!stateObj ${!stateObj
? html` ? html`
@ -143,6 +156,31 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
: undefined} : undefined}
.disabled=${this._submitting} .disabled=${this._submitting}
></ha-icon-picker> ></ha-icon-picker>
${OVERRIDE_DEVICE_CLASSES[domain]?.includes(this._deviceClass) ||
(domain === "cover" && this.entry.original_device_class === null)
? html`<ha-paper-dropdown-menu
.label=${this.hass.localize(
"ui.dialogs.entity_registry.editor.device_class"
)}
>
<paper-listbox
slot="dropdown-content"
attr-for-selected="item-value"
.selected=${this._deviceClass}
@selected-item-changed=${this._deviceClassChanged}
>
${OVERRIDE_DEVICE_CLASSES[domain].map(
(deviceClass: string) => html`
<paper-item .itemValue=${String(deviceClass)}>
${this.hass.localize(
`ui.dialogs.entity_registry.editor.device_classes.${domain}.${deviceClass}`
)}
</paper-item>
`
)}
</paper-listbox>
</ha-paper-dropdown-menu>`
: ""}
<paper-input <paper-input
.value=${this._entityId} .value=${this._entityId}
@value-changed=${this._entityIdChanged} @value-changed=${this._entityIdChanged}
@ -264,6 +302,15 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
this._entityId = ev.detail.value; this._entityId = ev.detail.value;
} }
private _deviceClassChanged(ev: PolymerChangedEvent<PaperItemElement>): 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) { private _areaPicked(ev: CustomEvent) {
this._error = undefined; this._error = undefined;
this._areaId = ev.detail.value; this._areaId = ev.detail.value;
@ -289,6 +336,7 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
name: this._name.trim() || null, name: this._name.trim() || null,
icon: this._icon.trim() || null, icon: this._icon.trim() || null,
area_id: this._areaId || null, area_id: this._areaId || null,
device_class: this._deviceClass || null,
new_entity_id: this._entityId.trim(), new_entity_id: this._entityId.trim(),
}; };
if ( if (
@ -378,6 +426,9 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
padding-bottom: max(env(safe-area-inset-bottom), 8px); padding-bottom: max(env(safe-area-inset-bottom), 8px);
background-color: var(--mdc-theme-surface, #fff); background-color: var(--mdc-theme-surface, #fff);
} }
ha-paper-dropdown-menu {
width: 100%;
}
ha-switch { ha-switch {
margin-right: 16px; margin-right: 16px;
} }

View File

@ -694,6 +694,20 @@
"icon": "Icon", "icon": "Icon",
"icon_error": "Icons should be in the format 'prefix:iconname', e.g. 'mdi:home'", "icon_error": "Icons should be in the format 'prefix:iconname', e.g. 'mdi:home'",
"entity_id": "Entity ID", "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.", "unavailable": "This entity is unavailable.",
"enabled_label": "Enable entity", "enabled_label": "Enable entity",
"enabled_cause": "Disabled by {cause}.", "enabled_cause": "Disabled by {cause}.",