mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 01:06:35 +00:00
Add default code to alarm_control_panel (#20062)
Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
This commit is contained in:
parent
febbf34de6
commit
91e5fcacd5
@ -10,8 +10,10 @@ import {
|
||||
HassEntityAttributeBase,
|
||||
HassEntityBase,
|
||||
} from "home-assistant-js-websocket";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { supportsFeature } from "../common/entity/supports-feature";
|
||||
import { showEnterCodeDialog } from "../dialogs/enter-code/show-enter-code-dialog";
|
||||
import { HomeAssistant } from "../types";
|
||||
import { getExtendedEntityRegistryEntry } from "./entity_registry";
|
||||
|
||||
export const FORMAT_TEXT = "text";
|
||||
export const FORMAT_NUMBER = "number";
|
||||
@ -103,3 +105,50 @@ export const supportedAlarmModes = (stateObj: AlarmControlPanelEntity) =>
|
||||
const feature = ALARM_MODES[mode].feature;
|
||||
return !feature || supportsFeature(stateObj, feature);
|
||||
});
|
||||
|
||||
export const setProtectedAlarmControlPanelMode = async (
|
||||
element: HTMLElement,
|
||||
hass: HomeAssistant,
|
||||
stateObj: AlarmControlPanelEntity,
|
||||
mode: AlarmMode
|
||||
) => {
|
||||
const { service } = ALARM_MODES[mode];
|
||||
|
||||
let code: string | undefined;
|
||||
|
||||
if (
|
||||
(mode !== "disarmed" &&
|
||||
stateObj.attributes.code_arm_required &&
|
||||
stateObj.attributes.code_format) ||
|
||||
(mode === "disarmed" && stateObj.attributes.code_format)
|
||||
) {
|
||||
const entry = await getExtendedEntityRegistryEntry(
|
||||
hass,
|
||||
stateObj.entity_id
|
||||
).catch(() => undefined);
|
||||
const defaultCode = entry?.options?.alarm_control_panel?.default_code;
|
||||
|
||||
if (!defaultCode) {
|
||||
const disarm = mode === "disarmed";
|
||||
|
||||
const response = await showEnterCodeDialog(element, {
|
||||
codeFormat: stateObj.attributes.code_format,
|
||||
title: hass.localize(
|
||||
`ui.card.alarm_control_panel.${disarm ? "disarm" : "arm"}`
|
||||
),
|
||||
submitText: hass.localize(
|
||||
`ui.card.alarm_control_panel.${disarm ? "disarm" : "arm"}`
|
||||
),
|
||||
});
|
||||
if (response == null) {
|
||||
throw new Error("Code dialog closed");
|
||||
}
|
||||
code = response;
|
||||
}
|
||||
}
|
||||
|
||||
await hass.callService("alarm_control_panel", service, {
|
||||
entity_id: stateObj.entity_id,
|
||||
code,
|
||||
});
|
||||
};
|
||||
|
@ -96,6 +96,10 @@ export interface LockEntityOptions {
|
||||
default_code?: string | null;
|
||||
}
|
||||
|
||||
export interface AlarmControlPanelEntityOptions {
|
||||
default_code?: string | null;
|
||||
}
|
||||
|
||||
export interface WeatherEntityOptions {
|
||||
precipitation_unit?: string | null;
|
||||
pressure_unit?: string | null;
|
||||
@ -112,6 +116,7 @@ export interface SwitchAsXEntityOptions {
|
||||
export interface EntityRegistryOptions {
|
||||
number?: NumberEntityOptions;
|
||||
sensor?: SensorEntityOptions;
|
||||
alarm_control_panel?: AlarmControlPanelEntityOptions;
|
||||
lock?: LockEntityOptions;
|
||||
weather?: WeatherEntityOptions;
|
||||
light?: LightEntityOptions;
|
||||
@ -134,6 +139,7 @@ export interface EntityRegistryEntryUpdateParams {
|
||||
| SensorEntityOptions
|
||||
| NumberEntityOptions
|
||||
| LockEntityOptions
|
||||
| AlarmControlPanelEntityOptions
|
||||
| WeatherEntityOptions
|
||||
| LightEntityOptions;
|
||||
aliases?: string[];
|
||||
|
@ -4,10 +4,12 @@ import { styleMap } from "lit/directives/style-map";
|
||||
import { stateColorCss } from "../../../common/entity/state_color";
|
||||
import "../../../components/ha-control-button";
|
||||
import "../../../components/ha-state-icon";
|
||||
import { AlarmControlPanelEntity } from "../../../data/alarm_control_panel";
|
||||
import {
|
||||
AlarmControlPanelEntity,
|
||||
setProtectedAlarmControlPanelMode,
|
||||
} from "../../../data/alarm_control_panel";
|
||||
import "../../../state-control/alarm_control_panel/ha-state-control-alarm_control_panel-modes";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { showEnterCodeDialog } from "../../enter-code/show-enter-code-dialog";
|
||||
import "../components/ha-more-info-state-header";
|
||||
import { moreInfoControlStyle } from "../components/more-info-control-style";
|
||||
|
||||
@ -18,24 +20,12 @@ class MoreInfoAlarmControlPanel extends LitElement {
|
||||
@property({ attribute: false }) public stateObj?: AlarmControlPanelEntity;
|
||||
|
||||
private async _disarm() {
|
||||
let code: string | undefined;
|
||||
|
||||
if (this.stateObj!.attributes.code_format) {
|
||||
const response = await showEnterCodeDialog(this, {
|
||||
codeFormat: this.stateObj!.attributes.code_format,
|
||||
title: this.hass.localize("ui.card.alarm_control_panel.disarm"),
|
||||
submitText: this.hass.localize("ui.card.alarm_control_panel.disarm"),
|
||||
});
|
||||
if (response == null) {
|
||||
return;
|
||||
}
|
||||
code = response;
|
||||
}
|
||||
|
||||
this.hass.callService("alarm_control_panel", "alarm_disarm", {
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
code,
|
||||
});
|
||||
setProtectedAlarmControlPanelMode(
|
||||
this,
|
||||
this.hass,
|
||||
this.stateObj!,
|
||||
"disarmed"
|
||||
);
|
||||
}
|
||||
|
||||
protected render() {
|
||||
|
@ -59,6 +59,7 @@ import {
|
||||
updateDeviceRegistryEntry,
|
||||
} from "../../../data/device_registry";
|
||||
import {
|
||||
AlarmControlPanelEntityOptions,
|
||||
EntityRegistryEntry,
|
||||
EntityRegistryEntryUpdateParams,
|
||||
ExtEntityRegistryEntry,
|
||||
@ -257,6 +258,10 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
this._defaultCode = this.entry.options?.lock?.default_code;
|
||||
}
|
||||
|
||||
if (domain === "alarm_control_panel") {
|
||||
this._defaultCode = this.entry.options?.alarm_control_panel?.default_code;
|
||||
}
|
||||
|
||||
if (domain === "weather") {
|
||||
const stateObj: HassEntity | undefined =
|
||||
this.hass.states[this.entry.entity_id];
|
||||
@ -583,6 +588,19 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
></ha-textfield>
|
||||
`
|
||||
: ""}
|
||||
${domain === "alarm_control_panel"
|
||||
? html`
|
||||
<ha-textfield
|
||||
.value=${this._defaultCode == null ? "" : this._defaultCode}
|
||||
.label=${this.hass.localize(
|
||||
"ui.dialogs.entity_registry.editor.default_code"
|
||||
)}
|
||||
type="password"
|
||||
.disabled=${this.disabled}
|
||||
@input=${this._defaultcodeChanged}
|
||||
></ha-textfield>
|
||||
`
|
||||
: ""}
|
||||
${domain === "sensor" &&
|
||||
this._deviceClass &&
|
||||
stateObj?.attributes.unit_of_measurement &&
|
||||
@ -1071,6 +1089,15 @@ export class EntityRegistrySettingsEditor extends LitElement {
|
||||
params.options = this.entry.options?.[domain] || {};
|
||||
(params.options as LockEntityOptions).default_code = this._defaultCode;
|
||||
}
|
||||
if (
|
||||
domain === "alarm_control_panel" &&
|
||||
this.entry.options?.[domain]?.default_code !== this._defaultCode
|
||||
) {
|
||||
params.options_domain = domain;
|
||||
params.options = this.entry.options?.[domain] || {};
|
||||
(params.options as AlarmControlPanelEntityOptions).default_code =
|
||||
this._defaultCode;
|
||||
}
|
||||
if (
|
||||
domain === "weather" &&
|
||||
(stateObj?.attributes?.precipitation_unit !== this._precipitation_unit ||
|
||||
|
@ -16,10 +16,10 @@ import {
|
||||
ALARM_MODES,
|
||||
AlarmControlPanelEntity,
|
||||
AlarmMode,
|
||||
setProtectedAlarmControlPanelMode,
|
||||
supportedAlarmModes,
|
||||
} from "../../../data/alarm_control_panel";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import { showEnterCodeDialog } from "../../../dialogs/enter-code/show-enter-code-dialog";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types";
|
||||
import { filterModes } from "./common/filter-modes";
|
||||
@ -115,37 +115,7 @@ class HuiAlarmModeCardFeature
|
||||
}
|
||||
|
||||
private async _setMode(mode: AlarmMode) {
|
||||
const { service } = ALARM_MODES[mode];
|
||||
|
||||
let code: string | undefined;
|
||||
|
||||
if (
|
||||
(mode !== "disarmed" &&
|
||||
this.stateObj!.attributes.code_arm_required &&
|
||||
this.stateObj!.attributes.code_format) ||
|
||||
(mode === "disarmed" && this.stateObj!.attributes.code_format)
|
||||
) {
|
||||
const disarm = mode === "disarmed";
|
||||
|
||||
const response = await showEnterCodeDialog(this, {
|
||||
codeFormat: this.stateObj!.attributes.code_format,
|
||||
title: this.hass!.localize(
|
||||
`ui.card.alarm_control_panel.${disarm ? "disarm" : "arm"}`
|
||||
),
|
||||
submitText: this.hass!.localize(
|
||||
`ui.card.alarm_control_panel.${disarm ? "disarm" : "arm"}`
|
||||
),
|
||||
});
|
||||
if (response == null) {
|
||||
throw new Error("cancel");
|
||||
}
|
||||
code = response;
|
||||
}
|
||||
|
||||
await this.hass!.callService("alarm_control_panel", service, {
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
code,
|
||||
});
|
||||
setProtectedAlarmControlPanelMode(this, this.hass!, this.stateObj!, mode);
|
||||
}
|
||||
|
||||
protected render(): TemplateResult | null {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||
import {
|
||||
CSSResultGroup,
|
||||
LitElement,
|
||||
@ -30,6 +30,11 @@ import type { HomeAssistant } from "../../../types";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type { LovelaceCard } from "../types";
|
||||
import {
|
||||
ExtEntityRegistryEntry,
|
||||
getExtendedEntityRegistryEntry,
|
||||
subscribeEntityRegistry,
|
||||
} from "../../../data/entity_registry";
|
||||
import { AlarmPanelCardConfig, AlarmPanelCardConfigState } from "./types";
|
||||
|
||||
const BUTTONS = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "clear"];
|
||||
@ -99,8 +104,22 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
|
||||
@state() private _config?: AlarmPanelCardConfig;
|
||||
|
||||
@state() private _entry?: ExtEntityRegistryEntry | null;
|
||||
|
||||
@query("#alarmCode") private _input?: HaTextField;
|
||||
|
||||
private _unsubEntityRegistry?: UnsubscribeFunc;
|
||||
|
||||
public connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this._subscribeEntityEntry();
|
||||
}
|
||||
|
||||
public disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
this._unsubscribeEntityRegistry();
|
||||
}
|
||||
|
||||
public async getCardSize(): Promise<number> {
|
||||
if (!this._config || !this.hass) {
|
||||
return 9;
|
||||
@ -123,6 +142,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
this._config = { ...config };
|
||||
this._subscribeEntityEntry();
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
@ -165,6 +185,36 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
);
|
||||
}
|
||||
|
||||
private async _unsubscribeEntityRegistry() {
|
||||
if (this._unsubEntityRegistry) {
|
||||
this._unsubEntityRegistry();
|
||||
this._unsubEntityRegistry = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async _subscribeEntityEntry() {
|
||||
if (!this._config?.entity) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this._unsubEntityRegistry = subscribeEntityRegistry(
|
||||
this.hass!.connection,
|
||||
async (entries) => {
|
||||
if (
|
||||
entries.some((entry) => entry.entity_id === this._config!.entity)
|
||||
) {
|
||||
this._entry = await getExtendedEntityRegistryEntry(
|
||||
this.hass!,
|
||||
this._config!.entity
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
this._entry = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (!this._config || !this.hass) {
|
||||
return nothing;
|
||||
@ -184,6 +234,8 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
|
||||
const stateLabel = this._stateDisplay(stateObj.state);
|
||||
|
||||
const defaultCode = this._entry?.options?.alarm_control_panel?.default_code;
|
||||
|
||||
return html`
|
||||
<ha-card>
|
||||
<h1 class="card-header">
|
||||
@ -222,7 +274,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
${!stateObj.attributes.code_format
|
||||
${!stateObj.attributes.code_format || defaultCode
|
||||
? nothing
|
||||
: html`
|
||||
<ha-textfield
|
||||
@ -234,7 +286,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
: "text"}
|
||||
></ha-textfield>
|
||||
`}
|
||||
${stateObj.attributes.code_format !== FORMAT_NUMBER
|
||||
${stateObj.attributes.code_format !== FORMAT_NUMBER || defaultCode
|
||||
? nothing
|
||||
: html`
|
||||
<div id="keypad">
|
||||
|
@ -11,9 +11,9 @@ import {
|
||||
ALARM_MODES,
|
||||
AlarmControlPanelEntity,
|
||||
AlarmMode,
|
||||
setProtectedAlarmControlPanelMode,
|
||||
} from "../../data/alarm_control_panel";
|
||||
import { UNAVAILABLE } from "../../data/entity";
|
||||
import { showEnterCodeDialog } from "../../dialogs/enter-code/show-enter-code-dialog";
|
||||
import { HomeAssistant } from "../../types";
|
||||
|
||||
@customElement("ha-state-control-alarm_control_panel-modes")
|
||||
@ -44,37 +44,7 @@ export class HaStateControlAlarmControlPanelModes extends LitElement {
|
||||
}
|
||||
|
||||
private async _setMode(mode: AlarmMode) {
|
||||
const { service } = ALARM_MODES[mode];
|
||||
|
||||
let code: string | undefined;
|
||||
|
||||
if (
|
||||
(mode !== "disarmed" &&
|
||||
this.stateObj!.attributes.code_arm_required &&
|
||||
this.stateObj!.attributes.code_format) ||
|
||||
(mode === "disarmed" && this.stateObj!.attributes.code_format)
|
||||
) {
|
||||
const disarm = mode === "disarmed";
|
||||
|
||||
const response = await showEnterCodeDialog(this, {
|
||||
codeFormat: this.stateObj!.attributes.code_format,
|
||||
title: this.hass!.localize(
|
||||
`ui.card.alarm_control_panel.${disarm ? "disarm" : "arm"}`
|
||||
),
|
||||
submitText: this.hass!.localize(
|
||||
`ui.card.alarm_control_panel.${disarm ? "disarmn" : "arm"}`
|
||||
),
|
||||
});
|
||||
if (response == null) {
|
||||
throw new Error("cancel");
|
||||
}
|
||||
code = response;
|
||||
}
|
||||
|
||||
await this.hass!.callService("alarm_control_panel", service, {
|
||||
entity_id: this.stateObj!.entity_id,
|
||||
code,
|
||||
});
|
||||
setProtectedAlarmControlPanelMode(this, this.hass!, this.stateObj!, mode);
|
||||
}
|
||||
|
||||
private async _valueChanged(ev: CustomEvent) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user