diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index c55578ffec..5bbb751eb2 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 90 days stale policy
- uses: actions/stale@v5.2.0
+ uses: actions/stale@v6.0.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 90
diff --git a/demo/src/ha-demo.ts b/demo/src/ha-demo.ts
index b583245e5a..b80c4d71de 100644
--- a/demo/src/ha-demo.ts
+++ b/demo/src/ha-demo.ts
@@ -68,6 +68,7 @@ class HaDemo extends HomeAssistantAppEl {
hidden_by: null,
entity_category: null,
has_entity_name: false,
+ unique_id: "co2_intensity",
},
{
config_entry_id: "co2signal",
@@ -82,6 +83,7 @@ class HaDemo extends HomeAssistantAppEl {
hidden_by: null,
entity_category: null,
has_entity_name: false,
+ unique_id: "grid_fossil_fuel_percentage",
},
]);
diff --git a/demo/src/stubs/energy.ts b/demo/src/stubs/energy.ts
index 00e7ef7c3f..80f10b968c 100644
--- a/demo/src/stubs/energy.ts
+++ b/demo/src/stubs/energy.ts
@@ -11,14 +11,12 @@ export const mockEnergy = (hass: MockHomeAssistant) => {
{
stat_energy_from: "sensor.energy_consumption_tarif_1",
stat_cost: "sensor.energy_consumption_tarif_1_cost",
- entity_energy_from: "sensor.energy_consumption_tarif_1",
entity_energy_price: null,
number_energy_price: null,
},
{
stat_energy_from: "sensor.energy_consumption_tarif_2",
stat_cost: "sensor.energy_consumption_tarif_2_cost",
- entity_energy_from: "sensor.energy_consumption_tarif_2",
entity_energy_price: null,
number_energy_price: null,
},
@@ -27,14 +25,12 @@ export const mockEnergy = (hass: MockHomeAssistant) => {
{
stat_energy_to: "sensor.energy_production_tarif_1",
stat_compensation: "sensor.energy_production_tarif_1_compensation",
- entity_energy_to: "sensor.energy_production_tarif_1",
entity_energy_price: null,
number_energy_price: null,
},
{
stat_energy_to: "sensor.energy_production_tarif_2",
stat_compensation: "sensor.energy_production_tarif_2_compensation",
- entity_energy_to: "sensor.energy_production_tarif_2",
entity_energy_price: null,
number_energy_price: null,
},
@@ -55,7 +51,6 @@ export const mockEnergy = (hass: MockHomeAssistant) => {
type: "gas",
stat_energy_from: "sensor.energy_gas",
stat_cost: "sensor.energy_gas_cost",
- entity_energy_from: "sensor.energy_gas",
entity_energy_price: null,
number_energy_price: null,
},
diff --git a/gallery/src/pages/misc/integration-card.ts b/gallery/src/pages/misc/integration-card.ts
index 7d3fc2eda4..5b6b064803 100644
--- a/gallery/src/pages/misc/integration-card.ts
+++ b/gallery/src/pages/misc/integration-card.ts
@@ -196,6 +196,7 @@ const createEntityRegistryEntries = (
icon: null,
platform: "updater",
has_entity_name: false,
+ unique_id: "updater",
},
];
diff --git a/script/core b/script/core
index 8ac6da6284..93b7021d57 100755
--- a/script/core
+++ b/script/core
@@ -46,6 +46,14 @@ frontend:
# development_repo: ${WD}" >> "${WD}/config/configuration.yaml"
fi
+ if [ ! -z "${CODESPACES}" ]; then
+ echo "
+http:
+ use_x_forwarded_for: true
+ trusted_proxies:
+ - 127.0.0.1
+" >> "${WD}/config/configuration.yaml"
+ fi
fi
hass -c "${WD}/config"
diff --git a/src/components/ha-selector/ha-selector-select.ts b/src/components/ha-selector/ha-selector-select.ts
index d051b5f125..c454d339cd 100644
--- a/src/components/ha-selector/ha-selector-select.ts
+++ b/src/components/ha-selector/ha-selector-select.ts
@@ -41,7 +41,7 @@ export class HaSelectSelector extends LitElement {
);
if (!this.selector.select.custom_value && this._mode === "list") {
- if (!this.selector.select.multiple || this.required) {
+ if (!this.selector.select.multiple) {
return html`
${this.label}
@@ -64,7 +64,8 @@ export class HaSelectSelector extends LitElement {
return html`
- ${this.label}${options.map(
+ ${this.label}
+ ${options.map(
(item: SelectOption) => html`
!item.disabled && !this.value?.includes(item.value)
+ (option) => !option.disabled && !value?.includes(option.value)
)}
@filter-changed=${this._filterChanged}
@value-changed=${this._comboBoxValueChanged}
@@ -290,6 +291,9 @@ export class HaSelectSelector extends LitElement {
ha-formfield {
display: block;
}
+ mwc-list-item[disabled] {
+ --mdc-theme-text-primary-on-background: var(--disabled-text-color);
+ }
`;
}
diff --git a/src/data/energy.ts b/src/data/energy.ts
index c8bb6cf55a..8420419978 100644
--- a/src/data/energy.ts
+++ b/src/data/energy.ts
@@ -29,7 +29,6 @@ export const emptyFlowFromGridSourceEnergyPreference =
(): FlowFromGridSourceEnergyPreference => ({
stat_energy_from: "",
stat_cost: null,
- entity_energy_from: null,
entity_energy_price: null,
number_energy_price: null,
});
@@ -38,7 +37,6 @@ export const emptyFlowToGridSourceEnergyPreference =
(): FlowToGridSourceEnergyPreference => ({
stat_energy_to: "",
stat_compensation: null,
- entity_energy_to: null,
entity_energy_price: null,
number_energy_price: null,
});
@@ -68,7 +66,6 @@ export const emptyGasEnergyPreference = (): GasSourceTypeEnergyPreference => ({
type: "gas",
stat_energy_from: "",
stat_cost: null,
- entity_energy_from: null,
entity_energy_price: null,
number_energy_price: null,
});
@@ -93,7 +90,6 @@ export interface FlowFromGridSourceEnergyPreference {
stat_cost: string | null;
// Can be used to generate costs if stat_cost omitted
- entity_energy_from: string | null;
entity_energy_price: string | null;
number_energy_price: number | null;
}
@@ -105,8 +101,7 @@ export interface FlowToGridSourceEnergyPreference {
// $ meter
stat_compensation: string | null;
- // Can be used to generate costs if stat_cost omitted
- entity_energy_to: string | null;
+ // Can be used to generate costs if stat_compensation omitted
entity_energy_price: string | null;
number_energy_price: number | null;
}
@@ -142,7 +137,6 @@ export interface GasSourceTypeEnergyPreference {
stat_cost: string | null;
// Can be used to generate costs if stat_cost omitted
- entity_energy_from: string | null;
entity_energy_price: string | null;
number_energy_price: number | null;
unit_of_measurement?: string | null;
diff --git a/src/data/entity_registry.ts b/src/data/entity_registry.ts
index 78da19f6f2..3802b26dca 100644
--- a/src/data/entity_registry.ts
+++ b/src/data/entity_registry.ts
@@ -20,10 +20,10 @@ export interface EntityRegistryEntry {
entity_category: "config" | "diagnostic" | null;
has_entity_name: boolean;
original_name?: string;
+ unique_id: string;
}
export interface ExtEntityRegistryEntry extends EntityRegistryEntry {
- unique_id: string;
capabilities: Record;
original_icon?: string;
device_class?: string;
@@ -61,7 +61,7 @@ export interface EntityRegistryEntryUpdateParams {
hidden_by: string | null;
new_entity_id?: string;
options_domain?: string;
- options?: SensorEntityOptions | WeatherEntityOptions;
+ options?: SensorEntityOptions | NumberEntityOptions | WeatherEntityOptions;
}
export const findBatteryEntity = (
diff --git a/src/data/lovelace.ts b/src/data/lovelace.ts
index 28d1c4886f..432cb6167b 100644
--- a/src/data/lovelace.ts
+++ b/src/data/lovelace.ts
@@ -93,6 +93,8 @@ export interface LovelaceViewConfig {
panel?: boolean;
background?: string;
visible?: boolean | ShowViewConfig[];
+ subview?: boolean;
+ back_path?: string;
}
export interface LovelaceViewElement extends HTMLElement {
diff --git a/src/data/zha.ts b/src/data/zha.ts
index fb0e2b0f31..55bf16d7c4 100644
--- a/src/data/zha.ts
+++ b/src/data/zha.ts
@@ -309,7 +309,7 @@ export const fetchCommandsForCluster = (
cluster_type: clusterType,
});
-export const fetchClustersForZhaNode = (
+export const fetchClustersForZhaDevice = (
hass: HomeAssistant,
ieeeAddress: string
): Promise =>
diff --git a/src/dialogs/more-info/ha-more-info-dialog.ts b/src/dialogs/more-info/ha-more-info-dialog.ts
index f07a3c3863..d47a02fbad 100644
--- a/src/dialogs/more-info/ha-more-info-dialog.ts
+++ b/src/dialogs/more-info/ha-more-info-dialog.ts
@@ -90,7 +90,7 @@ export class MoreInfoDialog extends LitElement {
const stateObj = this.hass.states[entityId];
const domain = computeDomain(entityId);
- const name = stateObj ? computeStateName(stateObj) : entityId;
+ const name = (stateObj && computeStateName(stateObj)) || entityId;
const tabs = this._getTabs(entityId, this.hass.user!.is_admin);
return html`
diff --git a/src/panels/config/application_credentials/dialog-add-application-credential.ts b/src/panels/config/application_credentials/dialog-add-application-credential.ts
index e01ded0e87..f1fc6ecf87 100644
--- a/src/panels/config/application_credentials/dialog-add-application-credential.ts
+++ b/src/panels/config/application_credentials/dialog-add-application-credential.ts
@@ -1,8 +1,9 @@
import "@material/mwc-button";
import "@material/mwc-list/mwc-list-item";
+import { mdiOpenInNew } from "@mdi/js";
+import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
-import { ComboBoxLitRenderer } from "@vaadin/combo-box/lit";
import { fireEvent } from "../../../common/dom/fire_event";
import "../../../components/ha-circular-progress";
import "../../../components/ha-combo-box";
@@ -10,14 +11,15 @@ import { createCloseHeading } from "../../../components/ha-dialog";
import "../../../components/ha-markdown";
import "../../../components/ha-textfield";
import {
- fetchApplicationCredentialsConfig,
- createApplicationCredential,
- ApplicationCredentialsConfig,
ApplicationCredential,
+ ApplicationCredentialsConfig,
+ createApplicationCredential,
+ fetchApplicationCredentialsConfig,
} from "../../../data/application_credential";
import { domainToName } from "../../../data/integration";
import { haStyleDialog } from "../../../resources/styles";
import { HomeAssistant } from "../../../types";
+import { documentationUrl } from "../../../util/documentation-url";
import { AddApplicationCredentialDialogParams } from "./show-dialog-add-application-credential";
interface Domain {
@@ -98,6 +100,25 @@ export class DialogAddApplicationCredential extends LitElement {
>
${this._loading
@@ -163,15 +192,18 @@ export class DialogAddApplicationCredential extends LitElement {
`
: html`
+
+ ${this.hass.localize("ui.common.cancel")}
+
${this.hass.localize(
- "ui.panel.config.application_credentials.editor.create"
+ "ui.panel.config.application_credentials.editor.add"
)}
`}
@@ -213,7 +245,7 @@ export class DialogAddApplicationCredential extends LitElement {
this.closeDialog();
}
- private async _createApplicationCredential(ev) {
+ private async _addApplicationCredential(ev) {
ev.preventDefault();
if (!this._domain || !this._clientId || !this._clientSecret) {
return;
@@ -260,6 +292,12 @@ export class DialogAddApplicationCredential extends LitElement {
display: block;
margin-bottom: 24px;
}
+ a {
+ text-decoration: none;
+ }
+ a ha-svg-icon {
+ --mdc-icon-size: 16px;
+ }
`,
];
}
diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts
index 627a052450..e7c7236fd3 100644
--- a/src/panels/config/automation/ha-automation-editor.ts
+++ b/src/panels/config/automation/ha-automation-editor.ts
@@ -575,10 +575,15 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
private async _deleteConfirm() {
showConfirmationDialog(this, {
+ title: this.hass.localize(
+ "ui.panel.config.automation.picker.delete_confirm_title"
+ ),
text: this.hass.localize(
- "ui.panel.config.automation.picker.delete_confirm"
+ "ui.panel.config.automation.picker.delete_confirm_text",
+ { name: this._config?.alias }
),
confirmText: this.hass!.localize("ui.common.delete"),
+ destructive: true,
dismissText: this.hass!.localize("ui.common.cancel"),
confirm: () => this._delete(),
});
diff --git a/src/panels/config/automation/ha-automation-picker.ts b/src/panels/config/automation/ha-automation-picker.ts
index dc395aefaf..3fe409f34b 100644
--- a/src/panels/config/automation/ha-automation-picker.ts
+++ b/src/panels/config/automation/ha-automation-picker.ts
@@ -341,12 +341,17 @@ class HaAutomationPicker extends LitElement {
private async _deleteConfirm(automation) {
showConfirmationDialog(this, {
+ title: this.hass.localize(
+ "ui.panel.config.automation.picker.delete_confirm_title"
+ ),
text: this.hass.localize(
- "ui.panel.config.automation.picker.delete_confirm"
+ "ui.panel.config.automation.picker.delete_confirm_text",
+ { name: automation.name }
),
confirmText: this.hass!.localize("ui.common.delete"),
dismissText: this.hass!.localize("ui.common.cancel"),
confirm: () => this._delete(automation),
+ destructive: true,
});
}
diff --git a/src/panels/config/blueprint/dialog-import-blueprint.ts b/src/panels/config/blueprint/dialog-import-blueprint.ts
index ef43378c16..1b97d52e8d 100644
--- a/src/panels/config/blueprint/dialog-import-blueprint.ts
+++ b/src/panels/config/blueprint/dialog-import-blueprint.ts
@@ -1,4 +1,5 @@
import "@material/mwc-button";
+import { mdiOpenInNew } from "@mdi/js";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
@@ -105,50 +106,61 @@ class DialogImportBlueprint extends LitElement {
>
${this._result.raw_data}
`
- : html`${this.hass.localize(
- "ui.panel.config.blueprint.add.import_introduction_link",
- "community_link",
- html`
${this.hass.localize(
- "ui.panel.config.blueprint.add.community_forums"
- )}`
- )}
+ ${this.hass.localize(
+ "ui.panel.config.blueprint.add.import_introduction"
+ )}
+
+
+ ${this.hass.localize(
+ "ui.panel.config.blueprint.add.community_forums"
+ )}
+
+
+ `}
+ >
+ `}
+
+ ${this.hass.localize("ui.common.cancel")}
+
${!this._result
- ? html`
- ${this._importing
- ? html``
- : ""}
- ${this.hass.localize("ui.panel.config.blueprint.add.import_btn")}
- `
- : html`
- ${this.hass.localize("ui.common.cancel")}
+ ${this._importing
+ ? html``
+ : ""}
+ ${this.hass.localize(
+ "ui.panel.config.blueprint.add.import_btn"
+ )}
+ `
+ : html`
`
: ""}
${this.hass.localize("ui.panel.config.blueprint.add.save_btn")}
- `}
+
+ `}
`;
}
@@ -215,9 +228,19 @@ class DialogImportBlueprint extends LitElement {
static styles = [
haStyleDialog,
css`
+ p {
+ margin-top: 0;
+ margin-bottom: 8px;
+ }
ha-textfield {
display: block;
- margin-top: 8px;
+ margin-top: 24px;
+ }
+ a {
+ text-decoration: none;
+ }
+ a ha-svg-icon {
+ --mdc-icon-size: 16px;
}
`,
];
diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts b/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts
index e9e17a3f20..907393e7c1 100644
--- a/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts
+++ b/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts
@@ -1,9 +1,7 @@
import {
mdiCogRefresh,
mdiDelete,
- mdiDrawPen,
mdiFamilyTree,
- mdiFileTree,
mdiGroup,
mdiPlus,
} from "@mdi/js";
@@ -12,9 +10,7 @@ import type { DeviceRegistryEntry } from "../../../../../../data/device_registry
import { fetchZHADevice } from "../../../../../../data/zha";
import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box";
import type { HomeAssistant } from "../../../../../../types";
-import { showZHAClusterDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-cluster";
-import { showZHADeviceChildrenDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-children";
-import { showZHADeviceZigbeeInfoDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info";
+import { showZHAManageZigbeeDeviceDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-manage-zigbee-device";
import { showZHAReconfigureDeviceDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-reconfigure-device";
import type { DeviceAction } from "../../../ha-config-device-page";
@@ -59,13 +55,6 @@ export const getZHADeviceActions = async (
icon: mdiPlus,
action: () => navigate(`/config/zha/add/${zhaDevice!.ieee}`),
},
- {
- label: hass.localize(
- "ui.dialogs.zha_device_info.buttons.device_children"
- ),
- icon: mdiFileTree,
- action: () => showZHADeviceChildrenDialog(el, { device: zhaDevice! }),
- },
]
);
}
@@ -73,16 +62,10 @@ export const getZHADeviceActions = async (
actions.push(
...[
{
- label: hass.localize(
- "ui.dialogs.zha_device_info.buttons.zigbee_information"
- ),
- icon: mdiDrawPen,
- action: () => showZHADeviceZigbeeInfoDialog(el, { device: zhaDevice }),
- },
- {
- label: hass.localize("ui.dialogs.zha_device_info.buttons.clusters"),
+ label: hass.localize("ui.dialogs.zha_device_info.buttons.manage"),
icon: mdiGroup,
- action: () => showZHAClusterDialog(el, { device: zhaDevice }),
+ action: () =>
+ showZHAManageZigbeeDeviceDialog(el, { device: zhaDevice }),
},
{
label: hass.localize("ui.dialogs.zha_device_info.buttons.view_network"),
diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts
index 5ccaf7c5e5..3f1f0fad16 100644
--- a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts
+++ b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts
@@ -23,6 +23,7 @@ export class HaDeviceActionsZha extends LitElement {
@state() private _zhaDevice?: ZHADevice;
protected updated(changedProperties: PropertyValues) {
+ super.updated(changedProperties);
if (changedProperties.has("device")) {
const zigbeeConnection = this.device.connections.find(
(conn) => conn[0] === "zigbee"
diff --git a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
index 2b382a40f4..e98621f903 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-gas-settings.ts
@@ -280,7 +280,6 @@ export class DialogEnergyGasSettings
this._source = {
...this._source!,
stat_energy_from: ev.detail.value,
- entity_energy_from: ev.detail.value,
};
}
diff --git a/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts b/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts
index a2d688f2b3..c2cab0d7b2 100644
--- a/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts
+++ b/src/panels/config/energy/dialogs/dialog-energy-grid-flow-settings.ts
@@ -269,9 +269,6 @@ export class DialogEnergyGridFlowSettings
[this._params!.direction === "from"
? "stat_energy_from"
: "stat_energy_to"]: ev.detail.value,
- [this._params!.direction === "from"
- ? "entity_energy_from"
- : "entity_energy_to"]: ev.detail.value,
};
}
diff --git a/src/panels/config/entities/entity-registry-settings.ts b/src/panels/config/entities/entity-registry-settings.ts
index 55ca2ac749..68e286d4f2 100644
--- a/src/panels/config/entities/entity-registry-settings.ts
+++ b/src/panels/config/entities/entity-registry-settings.ts
@@ -111,9 +111,12 @@ const OVERRIDE_NUMBER_UNITS = {
};
const OVERRIDE_SENSOR_UNITS = {
+ distance: ["cm", "ft", "in", "km", "m", "mi", "mm", "yd"],
mass: ["g", "kg", "lb", "mg", "oz", "µg"],
pressure: ["hPa", "Pa", "kPa", "bar", "cbar", "mbar", "mmHg", "inHg", "psi"],
+ speed: ["ft/s", "in/d", "in/h", "km/h", "kn", "m/s", "mm/d", "mph"],
temperature: ["°C", "°F", "K"],
+ volume: ["fl. oz.", "ft³", "gal", "L", "mL", "m³"],
};
const OVERRIDE_WEATHER_UNITS = {
diff --git a/src/panels/config/entities/ha-config-entities.ts b/src/panels/config/entities/ha-config-entities.ts
index ac02d2e048..8e3448994f 100644
--- a/src/panels/config/entities/ha-config-entities.ts
+++ b/src/panels/config/entities/ha-config-entities.ts
@@ -68,10 +68,12 @@ import type { HomeAssistant, Route } from "../../../types";
import { configSections } from "../ha-panel-config";
import "../integrations/ha-integration-overflow-menu";
-export interface StateEntity extends Omit {
+export interface StateEntity
+ extends Omit {
readonly?: boolean;
selectable?: boolean;
id?: string;
+ unique_id?: string;
}
export interface EntityRow extends StateEntity {
diff --git a/src/panels/config/integrations/integration-panels/zha/dialog-zha-cluster.ts b/src/panels/config/integrations/integration-panels/zha/dialog-zha-cluster.ts
deleted file mode 100644
index 84ea96c629..0000000000
--- a/src/panels/config/integrations/integration-panels/zha/dialog-zha-cluster.ts
+++ /dev/null
@@ -1,142 +0,0 @@
-import {
- CSSResultGroup,
- html,
- LitElement,
- PropertyValues,
- TemplateResult,
-} from "lit";
-import { customElement, property, state } from "lit/decorators";
-import { HASSDomEvent } from "../../../../../common/dom/fire_event";
-import "../../../../../components/ha-code-editor";
-import { createCloseHeading } from "../../../../../components/ha-dialog";
-import {
- Cluster,
- fetchBindableDevices,
- fetchGroups,
- ZHADevice,
- ZHAGroup,
-} from "../../../../../data/zha";
-import { haStyleDialog } from "../../../../../resources/styles";
-import { HomeAssistant } from "../../../../../types";
-import { sortZHADevices, sortZHAGroups } from "./functions";
-import { ZHADeviceZigbeeInfoDialogParams } from "./show-dialog-zha-device-zigbee-info";
-import { ZHAClusterSelectedParams } from "./types";
-import "./zha-cluster-attributes";
-import "./zha-cluster-commands";
-import "./zha-clusters";
-import "./zha-device-binding";
-import "./zha-group-binding";
-
-@customElement("dialog-zha-cluster")
-class DialogZHACluster extends LitElement {
- @property({ attribute: false }) public hass!: HomeAssistant;
-
- @state() private _device?: ZHADevice;
-
- @state() private _selectedCluster?: Cluster;
-
- @state() private _bindableDevices: ZHADevice[] = [];
-
- @state() private _groups: ZHAGroup[] = [];
-
- public async showDialog(
- params: ZHADeviceZigbeeInfoDialogParams
- ): Promise {
- this._device = params.device;
- }
-
- protected updated(changedProperties: PropertyValues): void {
- super.update(changedProperties);
- if (changedProperties.has("_device")) {
- this._fetchData();
- }
- }
-
- protected render(): TemplateResult {
- if (!this._device) {
- return html``;
- }
-
- return html`
-
-
- ${this._selectedCluster
- ? html`
-
-
- `
- : ""}
- ${this._bindableDevices.length > 0
- ? html`
-
- `
- : ""}
- ${this._device && this._groups.length > 0
- ? html`
-
- `
- : ""}
-
- `;
- }
-
- private _onClusterSelected(
- selectedClusterEvent: HASSDomEvent
- ): void {
- this._selectedCluster = selectedClusterEvent.detail.cluster;
- }
-
- private _close(): void {
- this._device = undefined;
- }
-
- private async _fetchData(): Promise {
- if (this._device && this.hass) {
- this._bindableDevices =
- this._device && this._device.device_type !== "Coordinator"
- ? (await fetchBindableDevices(this.hass, this._device.ieee)).sort(
- sortZHADevices
- )
- : [];
- this._groups = (await fetchGroups(this.hass!)).sort(sortZHAGroups);
- }
- }
-
- static get styles(): CSSResultGroup {
- return haStyleDialog;
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- "dialog-zha-cluster": DialogZHACluster;
- }
-}
diff --git a/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-zigbee-info.ts b/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-zigbee-info.ts
deleted file mode 100644
index b9334e46d4..0000000000
--- a/src/panels/config/integrations/integration-panels/zha/dialog-zha-device-zigbee-info.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
-import { customElement, property, state } from "lit/decorators";
-import "../../../../../components/ha-code-editor";
-import { createCloseHeading } from "../../../../../components/ha-dialog";
-import { haStyleDialog } from "../../../../../resources/styles";
-import { HomeAssistant } from "../../../../../types";
-import { ZHADeviceZigbeeInfoDialogParams } from "./show-dialog-zha-device-zigbee-info";
-
-@customElement("dialog-zha-device-zigbee-info")
-class DialogZHADeviceZigbeeInfo extends LitElement {
- @property({ attribute: false }) public hass!: HomeAssistant;
-
- @state() private _signature: any;
-
- public async showDialog(
- params: ZHADeviceZigbeeInfoDialogParams
- ): Promise {
- this._signature = JSON.stringify(
- {
- ...params.device.signature,
- manufacturer: params.device.manufacturer,
- model: params.device.model,
- class: params.device.quirk_class,
- },
- null,
- 2
- );
- }
-
- protected render(): TemplateResult {
- if (!this._signature) {
- return html``;
- }
-
- return html`
-
-
-
-
- `;
- }
-
- private _close(): void {
- this._signature = undefined;
- }
-
- static get styles(): CSSResultGroup {
- return haStyleDialog;
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- "dialog-zha-device-zigbee-info": DialogZHADeviceZigbeeInfo;
- }
-}
diff --git a/src/panels/config/integrations/integration-panels/zha/dialog-zha-manage-zigbee-device.ts b/src/panels/config/integrations/integration-panels/zha/dialog-zha-manage-zigbee-device.ts
new file mode 100644
index 0000000000..5ccacb9d90
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/zha/dialog-zha-manage-zigbee-device.ts
@@ -0,0 +1,291 @@
+import {
+ css,
+ CSSResultGroup,
+ html,
+ LitElement,
+ PropertyValues,
+ TemplateResult,
+} from "lit";
+import { mdiClose } from "@mdi/js";
+import { customElement, property, state } from "lit/decorators";
+import { cache } from "lit/directives/cache";
+import memoizeOne from "memoize-one";
+import { fireEvent } from "../../../../../common/dom/fire_event";
+import "../../../../../components/ha-code-editor";
+import { createCloseHeading } from "../../../../../components/ha-dialog";
+import {
+ fetchBindableDevices,
+ fetchGroups,
+ ZHADevice,
+ ZHAGroup,
+} from "../../../../../data/zha";
+import { haStyleDialog } from "../../../../../resources/styles";
+import { HomeAssistant } from "../../../../../types";
+import { sortZHADevices, sortZHAGroups } from "./functions";
+import "./zha-cluster-attributes";
+import "./zha-cluster-commands";
+import "./zha-manage-clusters";
+import "./zha-device-binding";
+import "./zha-group-binding";
+import "./zha-device-children";
+import "./zha-device-signature";
+import {
+ Tab,
+ ZHAManageZigbeeDeviceDialogParams,
+} from "./show-dialog-zha-manage-zigbee-device";
+import "../../../../../components/ha-header-bar";
+import "@material/mwc-tab-bar/mwc-tab-bar";
+import "@material/mwc-tab/mwc-tab";
+
+@customElement("dialog-zha-manage-zigbee-device")
+class DialogZHAManageZigbeeDevice extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ type: Boolean, reflect: true }) public large = false;
+
+ @state() private _currTab: Tab = "clusters";
+
+ @state() private _device?: ZHADevice;
+
+ @state() private _bindableDevices: ZHADevice[] = [];
+
+ @state() private _groups: ZHAGroup[] = [];
+
+ public async showDialog(
+ params: ZHAManageZigbeeDeviceDialogParams
+ ): Promise {
+ this._device = params.device;
+ if (!this._device) {
+ this.closeDialog();
+ return;
+ }
+ this._currTab = params.tab || "clusters";
+ this.large = false;
+ }
+
+ public closeDialog() {
+ this._device = undefined;
+ fireEvent(this, "dialog-closed", { dialog: this.localName });
+ }
+
+ protected firstUpdated(changedProps: PropertyValues) {
+ super.firstUpdated(changedProps);
+ this.addEventListener("close-dialog", () => this.closeDialog());
+ }
+
+ protected willUpdate(changedProps: PropertyValues) {
+ super.willUpdate(changedProps);
+ if (!this._device) {
+ return;
+ }
+ if (changedProps.has("_device")) {
+ const tabs = this._getTabs(this._device);
+ if (!tabs.includes(this._currTab)) {
+ this._currTab = tabs[0];
+ }
+ this._fetchData();
+ }
+ }
+
+ protected render(): TemplateResult {
+ if (!this._device) {
+ return html``;
+ }
+
+ const tabs = this._getTabs(this._device);
+
+ return html`
+
+
+
+
+
+ ${this.hass.localize("ui.dialogs.zha_manage_device.heading")}
+
+
+
+ ${tabs.map(
+ (tab) => html`
+
+ `
+ )}
+
+
+
+
+ ${cache(
+ this._currTab === "clusters"
+ ? html`
+
+ `
+ : this._currTab === "bindings"
+ ? html`
+ ${this._bindableDevices.length > 0
+ ? html`
+
+ `
+ : ""}
+ ${this._device && this._groups.length > 0
+ ? html`
+
+ `
+ : ""}
+ `
+ : this._currTab === "signature"
+ ? html`
+
+ `
+ : html`
+
+ `
+ )}
+
+
+ `;
+ }
+
+ private async _fetchData(): Promise {
+ if (this._device && this.hass) {
+ this._bindableDevices =
+ this._device && this._device.device_type !== "Coordinator"
+ ? (await fetchBindableDevices(this.hass, this._device.ieee)).sort(
+ sortZHADevices
+ )
+ : [];
+ this._groups = (await fetchGroups(this.hass!)).sort(sortZHAGroups);
+ }
+ }
+
+ private _enlarge() {
+ this.large = !this.large;
+ }
+
+ private _handleTabChanged(ev: CustomEvent): void {
+ const newTab = this._getTabs(this._device)[ev.detail.index];
+ if (newTab === this._currTab) {
+ return;
+ }
+ this._currTab = newTab;
+ }
+
+ private _getTabs = memoizeOne((device: ZHADevice | undefined) => {
+ const tabs: Tab[] = ["clusters", "bindings", "signature"];
+
+ if (
+ device &&
+ (device.device_type === "Router" || device.device_type === "Coordinator")
+ ) {
+ tabs.push("children");
+ }
+
+ return tabs;
+ });
+
+ static get styles(): CSSResultGroup {
+ return [
+ haStyleDialog,
+ css`
+ ha-dialog {
+ --dialog-surface-position: static;
+ --dialog-content-position: static;
+ --vertial-align-dialog: flex-start;
+ }
+
+ ha-header-bar {
+ --mdc-theme-on-primary: var(--primary-text-color);
+ --mdc-theme-primary: var(--mdc-theme-surface);
+ flex-shrink: 0;
+ display: block;
+ }
+ .content {
+ outline: none;
+ }
+ @media all and (max-width: 450px), all and (max-height: 500px) {
+ ha-header-bar {
+ --mdc-theme-primary: var(--app-header-background-color);
+ --mdc-theme-on-primary: var(--app-header-text-color, white);
+ border-bottom: none;
+ }
+ }
+
+ .heading {
+ border-bottom: 1px solid
+ var(--mdc-dialog-scroll-divider-color, rgba(0, 0, 0, 0.12));
+ }
+
+ @media all and (min-width: 600px) and (min-height: 501px) {
+ ha-dialog {
+ --mdc-dialog-min-width: 560px;
+ --mdc-dialog-max-width: 560px;
+ --dialog-surface-margin-top: 40px;
+ --mdc-dialog-max-height: calc(100% - 72px);
+ }
+
+ .main-title {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ cursor: default;
+ }
+
+ :host([large]) ha-dialog,
+ ha-dialog[data-domain="camera"] {
+ --mdc-dialog-min-width: 90vw;
+ --mdc-dialog-max-width: 90vw;
+ }
+ }
+ `,
+ ];
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "dialog-zha-manage-zigbee-device": DialogZHAManageZigbeeDevice;
+ }
+}
diff --git a/src/panels/config/integrations/integration-panels/zha/dialog-zha-reconfigure-device.ts b/src/panels/config/integrations/integration-panels/zha/dialog-zha-reconfigure-device.ts
index 1ae26ad04d..4c43266385 100644
--- a/src/panels/config/integrations/integration-panels/zha/dialog-zha-reconfigure-device.ts
+++ b/src/panels/config/integrations/integration-panels/zha/dialog-zha-reconfigure-device.ts
@@ -12,7 +12,7 @@ import {
Cluster,
ClusterConfigurationEvent,
ClusterConfigurationStatus,
- fetchClustersForZhaNode,
+ fetchClustersForZhaDevice,
reconfigureNode,
ZHA_CHANNEL_CFG_DONE,
ZHA_CHANNEL_MSG_BIND,
@@ -321,16 +321,16 @@ class DialogZHAReconfigureDevice extends LitElement {
return;
}
this._clusterConfigurationStatuses = new Map(
- (await fetchClustersForZhaNode(this.hass, this._params.device.ieee)).map(
- (cluster: Cluster) => [
- cluster.id,
- {
- cluster: cluster,
- bindSuccess: undefined,
- attributes: new Map(),
- },
- ]
- )
+ (
+ await fetchClustersForZhaDevice(this.hass, this._params.device.ieee)
+ ).map((cluster: Cluster) => [
+ cluster.id,
+ {
+ cluster: cluster,
+ bindSuccess: undefined,
+ attributes: new Map(),
+ },
+ ])
);
this._subscribe(this._params);
this._status = "started";
diff --git a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-cluster.ts b/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-cluster.ts
deleted file mode 100644
index 9b0c44ad5d..0000000000
--- a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-cluster.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import { fireEvent } from "../../../../../common/dom/fire_event";
-import { ZHADevice } from "../../../../../data/zha";
-
-export interface ZHAClusterDialogParams {
- device: ZHADevice;
-}
-
-export const loadZHAClusterDialog = () => import("./dialog-zha-cluster");
-
-export const showZHAClusterDialog = (
- element: HTMLElement,
- params: ZHAClusterDialogParams
-): void => {
- fireEvent(element, "show-dialog", {
- dialogTag: "dialog-zha-cluster",
- dialogImport: loadZHAClusterDialog,
- dialogParams: params,
- });
-};
diff --git a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-device-children.ts b/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-device-children.ts
deleted file mode 100644
index f8a3e64ab0..0000000000
--- a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-device-children.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { fireEvent } from "../../../../../common/dom/fire_event";
-import { ZHADevice } from "../../../../../data/zha";
-
-export interface ZHADeviceChildrenDialogParams {
- device: ZHADevice;
-}
-
-export const loadZHADeviceChildrenDialog = () =>
- import("./dialog-zha-device-children");
-
-export const showZHADeviceChildrenDialog = (
- element: HTMLElement,
- zhaDeviceChildrenParams: ZHADeviceChildrenDialogParams
-): void => {
- fireEvent(element, "show-dialog", {
- dialogTag: "dialog-zha-device-children",
- dialogImport: loadZHADeviceChildrenDialog,
- dialogParams: zhaDeviceChildrenParams,
- });
-};
diff --git a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info.ts b/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info.ts
deleted file mode 100644
index e4a2191563..0000000000
--- a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-import { fireEvent } from "../../../../../common/dom/fire_event";
-import { ZHADevice } from "../../../../../data/zha";
-
-export interface ZHADeviceZigbeeInfoDialogParams {
- device: ZHADevice;
-}
-
-export const loadZHADeviceZigbeeInfoDialog = () =>
- import("./dialog-zha-device-zigbee-info");
-
-export const showZHADeviceZigbeeInfoDialog = (
- element: HTMLElement,
- zhaDeviceZigbeeInfoParams: ZHADeviceZigbeeInfoDialogParams
-): void => {
- fireEvent(element, "show-dialog", {
- dialogTag: "dialog-zha-device-zigbee-info",
- dialogImport: loadZHADeviceZigbeeInfoDialog,
- dialogParams: zhaDeviceZigbeeInfoParams,
- });
-};
diff --git a/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-manage-zigbee-device.ts b/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-manage-zigbee-device.ts
new file mode 100644
index 0000000000..a2854748ff
--- /dev/null
+++ b/src/panels/config/integrations/integration-panels/zha/show-dialog-zha-manage-zigbee-device.ts
@@ -0,0 +1,23 @@
+import { fireEvent } from "../../../../../common/dom/fire_event";
+import { ZHADevice } from "../../../../../data/zha";
+
+export type Tab = "clusters" | "bindings" | "signature" | "children";
+
+export interface ZHAManageZigbeeDeviceDialogParams {
+ device: ZHADevice;
+ tab?: Tab;
+}
+
+export const loadZHAManageZigbeeDeviceDialog = () =>
+ import("./dialog-zha-manage-zigbee-device");
+
+export const showZHAManageZigbeeDeviceDialog = (
+ element: HTMLElement,
+ params: ZHAManageZigbeeDeviceDialogParams
+): void => {
+ fireEvent(element, "show-dialog", {
+ dialogTag: "dialog-zha-manage-zigbee-device",
+ dialogImport: loadZHAManageZigbeeDeviceDialog,
+ dialogParams: params,
+ });
+};
diff --git a/src/panels/config/integrations/integration-panels/zha/types.ts b/src/panels/config/integrations/integration-panels/zha/types.ts
index dbc2954f2d..3e9af96a18 100644
--- a/src/panels/config/integrations/integration-panels/zha/types.ts
+++ b/src/panels/config/integrations/integration-panels/zha/types.ts
@@ -1,5 +1,5 @@
import { HaSelect } from "../../../../../components/ha-select";
-import { Cluster, ZHADevice } from "../../../../../data/zha";
+import { ZHADevice } from "../../../../../data/zha";
export interface ItemSelectedEvent {
target?: HaSelect;
@@ -41,10 +41,6 @@ export interface ZHADeviceSelectedParams {
node: ZHADevice;
}
-export interface ZHAClusterSelectedParams {
- cluster: Cluster;
-}
-
export interface NodeServiceData {
ieee_address: string;
}
diff --git a/src/panels/config/integrations/integration-panels/zha/zha-cluster-attributes.ts b/src/panels/config/integrations/integration-panels/zha/zha-cluster-attributes.ts
index c764a135b3..a0a3695dea 100644
--- a/src/panels/config/integrations/integration-panels/zha/zha-cluster-attributes.ts
+++ b/src/panels/config/integrations/integration-panels/zha/zha-cluster-attributes.ts
@@ -1,6 +1,4 @@
-import "@material/mwc-button";
import "@material/mwc-list/mwc-list-item";
-import { mdiHelpCircle } from "@mdi/js";
import "@polymer/paper-input/paper-input";
import {
css,
@@ -10,13 +8,12 @@ import {
PropertyValues,
TemplateResult,
} from "lit";
-import { property, state } from "lit/decorators";
+import { customElement, property, state } from "lit/decorators";
import { stopPropagation } from "../../../../../common/dom/stop_propagation";
import "../../../../../components/buttons/ha-call-service-button";
import "../../../../../components/ha-card";
-import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-select";
-import "../../../../../components/ha-service-description";
+import "../../../../../components/buttons/ha-progress-button";
import {
Attribute,
Cluster,
@@ -27,7 +24,7 @@ import {
} from "../../../../../data/zha";
import { haStyle } from "../../../../../resources/styles";
import { HomeAssistant } from "../../../../../types";
-import "../../../ha-config-section";
+import { forwardHaptic } from "../../../../../data/haptics";
import { formatAsPaddedHex } from "./functions";
import {
ChangeEvent,
@@ -35,18 +32,15 @@ import {
SetAttributeServiceData,
} from "./types";
+@customElement("zha-cluster-attributes")
export class ZHAClusterAttributes extends LitElement {
@property({ attribute: false }) public hass?: HomeAssistant;
- @property() public isWide?: boolean;
-
- @property() public showHelp = false;
-
- @property() public selectedNode?: ZHADevice;
+ @property() public device?: ZHADevice;
@property() public selectedCluster?: Cluster;
- @state() private _attributes: Attribute[] = [];
+ @state() private _attributes: Attribute[] | undefined;
@state() private _selectedAttributeId?: number;
@@ -54,78 +48,52 @@ export class ZHAClusterAttributes extends LitElement {
@state() private _manufacturerCodeOverride?: string | number;
+ @state() private _readingAttribute = false;
+
@state()
private _setAttributeServiceData?: SetAttributeServiceData;
protected updated(changedProperties: PropertyValues): void {
if (changedProperties.has("selectedCluster")) {
- this._attributes = [];
+ this._attributes = undefined;
this._selectedAttributeId = undefined;
this._attributeValue = "";
this._fetchAttributesForCluster();
}
- super.update(changedProperties);
+ super.updated(changedProperties);
}
protected render(): TemplateResult {
+ if (!this.device || !this.selectedCluster || !this._attributes) {
+ return html``;
+ }
return html`
-
-
+ ${this._selectedAttributeId !== undefined
+ ? this._renderAttributeInteractions()
+ : ""}
+
`;
}
@@ -152,20 +120,15 @@ export class ZHAClusterAttributes extends LitElement {
>
-
+
${this.hass!.localize(
- "ui.panel.config.zha.cluster_attributes.get_zigbee_attribute"
+ "ui.panel.config.zha.cluster_attributes.read_zigbee_attribute"
)}
-
- ${this.showHelp
- ? html`
-
- ${this.hass!.localize(
- "ui.panel.config.zha.cluster_attributes.help_get_zigbee_attribute"
- )}
-
- `
- : ""}
+
${this.hass!.localize(
- "ui.panel.config.zha.cluster_attributes.set_zigbee_attribute"
+ "ui.panel.config.zha.cluster_attributes.write_zigbee_attribute"
)}
- ${this.showHelp
- ? html`
-
- `
- : ""}
`;
}
private async _fetchAttributesForCluster(): Promise {
- if (this.selectedNode && this.selectedCluster && this.hass) {
+ if (this.device && this.selectedCluster && this.hass) {
this._attributes = await fetchAttributesForCluster(
this.hass,
- this.selectedNode!.ieee,
+ this.device!.ieee,
this.selectedCluster!.endpoint_id,
this.selectedCluster!.id,
this.selectedCluster!.type
);
this._attributes.sort((a, b) => a.name.localeCompare(b.name));
+ if (this._attributes.length > 0) {
+ this._selectedAttributeId = this._attributes[0].id;
+ }
}
}
private _computeReadAttributeServiceData():
| ReadAttributeServiceData
| undefined {
- if (!this.selectedCluster || !this.selectedNode) {
+ if (!this.selectedCluster || !this.device) {
return undefined;
}
return {
- ieee: this.selectedNode!.ieee,
+ ieee: this.device!.ieee,
endpoint_id: this.selectedCluster!.endpoint_id,
cluster_id: this.selectedCluster!.id,
cluster_type: this.selectedCluster!.type,
@@ -224,11 +180,11 @@ export class ZHAClusterAttributes extends LitElement {
private _computeSetAttributeServiceData():
| SetAttributeServiceData
| undefined {
- if (!this.selectedCluster || !this.selectedNode) {
+ if (!this.selectedCluster || !this.device) {
return undefined;
}
return {
- ieee: this.selectedNode!.ieee,
+ ieee: this.device!.ieee,
endpoint_id: this.selectedCluster!.endpoint_id,
cluster_id: this.selectedCluster!.id,
cluster_type: this.selectedCluster!.type,
@@ -250,17 +206,24 @@ export class ZHAClusterAttributes extends LitElement {
this._setAttributeServiceData = this._computeSetAttributeServiceData();
}
- private async _onGetZigbeeAttributeClick(): Promise {
+ private async _onGetZigbeeAttributeClick(ev: CustomEvent): Promise {
+ const button = ev.currentTarget as any;
const data = this._computeReadAttributeServiceData();
if (data && this.hass) {
- this._attributeValue = await readAttributeValue(this.hass, data);
+ this._readingAttribute = true;
+ try {
+ this._attributeValue = await readAttributeValue(this.hass, data);
+ forwardHaptic("success");
+ button.actionSuccess();
+ } catch (err: any) {
+ forwardHaptic("failure");
+ button.actionError();
+ } finally {
+ this._readingAttribute = false;
+ }
}
}
- private _onHelpTap(): void {
- this.showHelp = !this.showHelp;
- }
-
private _selectedAttributeChanged(event: ItemSelectedEvent): void {
this._selectedAttributeId = Number(event.target!.value);
this._attributeValue = "";
@@ -278,14 +241,6 @@ export class ZHAClusterAttributes extends LitElement {
width: 100%;
}
- .content {
- margin-top: 24px;
- }
-
- ha-card {
- max-width: 680px;
- }
-
.card-actions.warning ha-call-service-button {
color: var(--error-color);
}
@@ -306,33 +261,6 @@ export class ZHAClusterAttributes extends LitElement {
.header {
flex-grow: 1;
}
-
- .toggle-help-icon {
- float: right;
- top: -6px;
- right: 0;
- padding-right: 0px;
- color: var(--primary-color);
- }
-
- ha-service-description {
- display: block;
- color: grey;
- }
-
- [hidden] {
- display: none;
- }
- .help-text {
- color: grey;
- padding-left: 28px;
- padding-right: 28px;
- padding-bottom: 16px;
- }
- .help-text2 {
- color: grey;
- padding: 16px;
- }
`,
];
}
@@ -343,5 +271,3 @@ declare global {
"zha-cluster-attributes": ZHAClusterAttributes;
}
}
-
-customElements.define("zha-cluster-attributes", ZHAClusterAttributes);
diff --git a/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts b/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts
index ca3a29be5f..129e42e74f 100644
--- a/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts
+++ b/src/panels/config/integrations/integration-panels/zha/zha-cluster-commands.ts
@@ -1,5 +1,4 @@
import "@material/mwc-list/mwc-list-item";
-import { mdiHelpCircle } from "@mdi/js";
import "@polymer/paper-input/paper-input";
import {
css,
@@ -13,9 +12,7 @@ import { property, state } from "lit/decorators";
import { stopPropagation } from "../../../../../common/dom/stop_propagation";
import "../../../../../components/buttons/ha-call-service-button";
import "../../../../../components/ha-card";
-import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-select";
-import "../../../../../components/ha-service-description";
import {
Cluster,
Command,
@@ -24,7 +21,6 @@ import {
} from "../../../../../data/zha";
import { haStyle } from "../../../../../resources/styles";
import { HomeAssistant } from "../../../../../types";
-import "../../../ha-config-section";
import { formatAsPaddedHex } from "./functions";
import { ChangeEvent, IssueCommandServiceData } from "./types";
@@ -33,13 +29,11 @@ export class ZHAClusterCommands extends LitElement {
@property() public isWide?: boolean;
- @property() public selectedNode?: ZHADevice;
+ @property() public device?: ZHADevice;
@property() public selectedCluster?: Cluster;
- @state() private _showHelp = false;
-
- @state() private _commands: Command[] = [];
+ @state() private _commands: Command[] | undefined;
@state() private _selectedCommandId?: number;
@@ -50,132 +44,97 @@ export class ZHAClusterCommands extends LitElement {
protected updated(changedProperties: PropertyValues): void {
if (changedProperties.has("selectedCluster")) {
- this._commands = [];
+ this._commands = undefined;
this._selectedCommandId = undefined;
this._fetchCommandsForCluster();
}
- super.update(changedProperties);
+ super.updated(changedProperties);
}
protected render(): TemplateResult {
+ if (!this.device || !this.selectedCluster || !this._commands) {
+ return html``;
+ }
return html`
-
-