diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index 8fcf28ab4e..b24f4f7cc3 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -5,8 +5,9 @@ import { Statistic, StatisticType } from "../../../data/recorder"; import { ForecastType } from "../../../data/weather"; import { FullCalendarView, TranslationDict } from "../../../types"; import { LovelaceCardFeatureConfig } from "../card-features/types"; +import { LovelaceCondition } from "../common/conditions/types"; import { LegacyStateFilter } from "../common/evaluate-filter"; -import { Condition, LegacyCondition } from "../common/validate-condition"; +import { LegacyCondition } from "../common/validate-condition"; import { HuiImage } from "../components/hui-image"; import { TimestampRenderingFormat } from "../components/types"; import { LovelaceElementConfig } from "../elements/types"; @@ -40,7 +41,7 @@ export interface CalendarCardConfig extends LovelaceCardConfig { export interface ConditionalCardConfig extends LovelaceCardConfig { card: LovelaceCardConfig; - conditions: (Condition | LegacyCondition)[]; + conditions: (LovelaceCondition | LegacyCondition)[]; } export interface EmptyStateCardConfig extends LovelaceCardConfig { @@ -203,7 +204,7 @@ export interface EntityFilterCardConfig extends LovelaceCardConfig { type: "entity-filter"; entities: Array; state_filter?: Array; - conditions: Array; + conditions: Array; card?: Partial; show_empty?: boolean; } diff --git a/src/panels/lovelace/common/conditions/condition-and.ts b/src/panels/lovelace/common/conditions/condition-and.ts new file mode 100644 index 0000000000..faa4e3fd51 --- /dev/null +++ b/src/panels/lovelace/common/conditions/condition-and.ts @@ -0,0 +1,21 @@ +import { HomeAssistant } from "../../../../types"; +import { ConditionHandler, checkCondition } from "./handle-condition"; +import { LovelaceBaseCondition, LovelaceCondition } from "./types"; + +export type LovelaceAndCondition = LovelaceBaseCondition & { + condition: "and"; + conditions?: LovelaceCondition[]; +}; + +export class AndConditionHandler + implements ConditionHandler +{ + validate(condition: LovelaceAndCondition): boolean { + return condition.conditions != null; + } + + check(condition: LovelaceAndCondition, hass: HomeAssistant): boolean { + if (!condition.conditions) return true; + return condition.conditions.every((c) => checkCondition(c, hass)); + } +} diff --git a/src/panels/lovelace/common/conditions/condition-numeric-state.ts b/src/panels/lovelace/common/conditions/condition-numeric-state.ts new file mode 100644 index 0000000000..309a005362 --- /dev/null +++ b/src/panels/lovelace/common/conditions/condition-numeric-state.ts @@ -0,0 +1,64 @@ +import { isValidEntityId } from "../../../../common/entity/valid_entity_id"; +import { HomeAssistant } from "../../../../types"; +import { ConditionHandler } from "./handle-condition"; +import { LovelaceBaseCondition } from "./types"; + +function getValueFromEntityId(hass: HomeAssistant, value: string): string { + if (isValidEntityId(value) && hass.states[value]) { + return hass.states[value]?.state; + } + return value; +} + +export type LovelaceNumericStateCondition = LovelaceBaseCondition & { + condition: "numeric_state"; + entity?: string; + below?: string | number; + above?: string | number; +}; + +export class NumericStateConditionHandler + implements ConditionHandler +{ + validate(condition: LovelaceNumericStateCondition): boolean { + return ( + condition.entity != null && + (condition.above != null || condition.below != null) + ); + } + + check( + condition: LovelaceNumericStateCondition, + hass: HomeAssistant + ): boolean { + const state = (condition.entity ? hass.states[condition.entity] : undefined) + ?.state; + let above = condition.above; + let below = condition.below; + + // Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now) + if (typeof above === "string") { + above = getValueFromEntityId(hass, above) as string; + } + if (typeof below === "string") { + below = getValueFromEntityId(hass, below) as string; + } + + const numericState = Number(state); + const numericAbove = Number(above); + const numericBelow = Number(below); + + if (isNaN(numericState)) { + return false; + } + + return ( + (condition.above == null || + isNaN(numericAbove) || + numericAbove < numericState) && + (condition.below == null || + isNaN(numericBelow) || + numericBelow > numericState) + ); + } +} diff --git a/src/panels/lovelace/common/conditions/condition-or.ts b/src/panels/lovelace/common/conditions/condition-or.ts new file mode 100644 index 0000000000..2a4d0dfca5 --- /dev/null +++ b/src/panels/lovelace/common/conditions/condition-or.ts @@ -0,0 +1,21 @@ +import { HomeAssistant } from "../../../../types"; +import { ConditionHandler, checkCondition } from "./handle-condition"; +import { LovelaceBaseCondition, LovelaceCondition } from "./types"; + +export type LovelaceOrCondition = LovelaceBaseCondition & { + condition: "or"; + conditions?: LovelaceCondition[]; +}; + +export class OrConditionHandler + implements ConditionHandler +{ + validate(condition: LovelaceOrCondition): boolean { + return condition.conditions != null; + } + + check(condition: LovelaceOrCondition, hass: HomeAssistant): boolean { + if (!condition.conditions) return true; + return condition.conditions.some((c) => checkCondition(c, hass)); + } +} diff --git a/src/panels/lovelace/common/conditions/condition-screen.ts b/src/panels/lovelace/common/conditions/condition-screen.ts new file mode 100644 index 0000000000..c86192f84f --- /dev/null +++ b/src/panels/lovelace/common/conditions/condition-screen.ts @@ -0,0 +1,22 @@ +import { HomeAssistant } from "../../../../types"; +import { ConditionHandler } from "./handle-condition"; +import { LovelaceBaseCondition } from "./types"; + +export type LovelaceScreenCondition = LovelaceBaseCondition & { + condition: "screen"; + media_query?: string; +}; + +export class ScreenConditionHandler + implements ConditionHandler +{ + validate(condition: LovelaceScreenCondition): boolean { + return condition.media_query != null; + } + + check(condition: LovelaceScreenCondition, _hass: HomeAssistant): boolean { + return condition.media_query + ? window.matchMedia(condition.media_query).matches + : false; + } +} diff --git a/src/panels/lovelace/common/conditions/condition-state.ts b/src/panels/lovelace/common/conditions/condition-state.ts new file mode 100644 index 0000000000..7a1afd7a6a --- /dev/null +++ b/src/panels/lovelace/common/conditions/condition-state.ts @@ -0,0 +1,50 @@ +import { ensureArray } from "../../../../common/array/ensure-array"; +import { isValidEntityId } from "../../../../common/entity/valid_entity_id"; +import { UNAVAILABLE } from "../../../../data/entity"; +import { HomeAssistant } from "../../../../types"; +import { ConditionHandler } from "./handle-condition"; +import { LovelaceBaseCondition } from "./types"; + +function getValueFromEntityId(hass: HomeAssistant, value: string): string { + if (isValidEntityId(value) && hass.states[value]) { + return hass.states[value]?.state; + } + return value; +} + +export type LovelaceStateCondition = LovelaceBaseCondition & { + condition: "state"; + entity?: string; + state?: string | string[]; + state_not?: string | string[]; +}; + +export class StateConditionHandler + implements ConditionHandler +{ + validate(condition: LovelaceStateCondition): boolean { + return ( + condition.entity != null && + (condition.state != null || condition.state_not != null) + ); + } + + check(condition: LovelaceStateCondition, hass: HomeAssistant): boolean { + const state = + condition.entity && hass.states[condition.entity] + ? hass.states[condition.entity].state + : UNAVAILABLE; + let value = condition.state ?? condition.state_not; + + if (typeof value === "string") { + value = getValueFromEntityId(hass, value); + } + if (Array.isArray(value)) { + value = value.map((val) => getValueFromEntityId(hass, val)); + } + + return condition.state != null + ? ensureArray(value).includes(state) + : !ensureArray(value).includes(state); + } +} diff --git a/src/panels/lovelace/common/conditions/condition-user.ts b/src/panels/lovelace/common/conditions/condition-user.ts new file mode 100644 index 0000000000..ac8e11281d --- /dev/null +++ b/src/panels/lovelace/common/conditions/condition-user.ts @@ -0,0 +1,22 @@ +import { HomeAssistant } from "../../../../types"; +import { ConditionHandler } from "./handle-condition"; +import { LovelaceBaseCondition } from "./types"; + +export type LovelaceUserCondition = LovelaceBaseCondition & { + condition: "user"; + users?: string[]; +}; + +export class UserConditionHandler + implements ConditionHandler +{ + validate(condition: LovelaceUserCondition): boolean { + return condition.users != null; + } + + check(condition: LovelaceUserCondition, hass: HomeAssistant): boolean { + return condition.users && hass.user?.id + ? condition.users.includes(hass.user.id) + : false; + } +} diff --git a/src/panels/lovelace/common/conditions/handle-condition.ts b/src/panels/lovelace/common/conditions/handle-condition.ts new file mode 100644 index 0000000000..7b3b033884 --- /dev/null +++ b/src/panels/lovelace/common/conditions/handle-condition.ts @@ -0,0 +1,35 @@ +import { HomeAssistant } from "../../../../types"; +import { AndConditionHandler } from "./condition-and"; +import { NumericStateConditionHandler } from "./condition-numeric-state"; +import { OrConditionHandler } from "./condition-or"; +import { ScreenConditionHandler } from "./condition-screen"; +import { StateConditionHandler } from "./condition-state"; +import { UserConditionHandler } from "./condition-user"; +import { LovelaceBaseCondition, LovelaceCondition } from "./types"; + +export interface ConditionHandler< + T extends LovelaceBaseCondition = LovelaceBaseCondition, +> { + validate(condition: T): boolean; + check(condition: T, hass: HomeAssistant): boolean; +} + +const HANDLER: Record = { + state: new StateConditionHandler(), + numeric_state: new NumericStateConditionHandler(), + screen: new ScreenConditionHandler(), + and: new AndConditionHandler(), + or: new OrConditionHandler(), + user: new UserConditionHandler(), +}; + +export function checkCondition( + condition: LovelaceCondition, + hass: HomeAssistant +): boolean { + return HANDLER[condition.condition].check(condition, hass); +} + +export function validateCondition(condition: LovelaceCondition): boolean { + return HANDLER[condition.condition].validate(condition); +} diff --git a/src/panels/lovelace/common/conditions/types.ts b/src/panels/lovelace/common/conditions/types.ts new file mode 100644 index 0000000000..bfbeeba04d --- /dev/null +++ b/src/panels/lovelace/common/conditions/types.ts @@ -0,0 +1,45 @@ +export type LovelaceCondition = + | LovelaceNumericStateCondition + | LovelaceStateCondition + | LovelaceScreenCondition + | LovelaceOrCondition + | LovelaceAndCondition + | LovelaceUserCondition; + +export type LovelaceBaseCondition = { + condition: string; +}; + +export type LovelaceNumericStateCondition = LovelaceBaseCondition & { + condition: "numeric_state"; + entity?: string; + below?: string | number; + above?: string | number; +}; + +export type LovelaceStateCondition = LovelaceBaseCondition & { + condition: "state"; + entity?: string; + state?: string | string[]; + state_not?: string | string[]; +}; + +export type LovelaceScreenCondition = LovelaceBaseCondition & { + condition: "screen"; + media_query?: string; +}; + +export type LovelaceUserCondition = LovelaceBaseCondition & { + condition: "user"; + users?: string[]; +}; + +export type LovelaceOrCondition = LovelaceBaseCondition & { + condition: "or"; + conditions?: LovelaceCondition[]; +}; + +export type LovelaceAndCondition = LovelaceBaseCondition & { + condition: "and"; + conditions?: LovelaceCondition[]; +}; diff --git a/src/panels/lovelace/common/validate-condition.ts b/src/panels/lovelace/common/validate-condition.ts index 0a3a35809d..1fc03eacee 100644 --- a/src/panels/lovelace/common/validate-condition.ts +++ b/src/panels/lovelace/common/validate-condition.ts @@ -1,15 +1,11 @@ import { ensureArray } from "../../../common/array/ensure-array"; import { isValidEntityId } from "../../../common/entity/valid_entity_id"; -import { UNAVAILABLE } from "../../../data/entity"; import { HomeAssistant } from "../../../types"; - -export type Condition = - | NumericStateCondition - | StateCondition - | ScreenCondition - | UserCondition - | OrCondition - | AndCondition; +import { + checkCondition, + validateCondition, +} from "./conditions/handle-condition"; +import { LovelaceCondition } from "./conditions/types"; // Legacy conditional card condition export interface LegacyCondition { @@ -18,131 +14,6 @@ export interface LegacyCondition { state_not?: string | string[]; } -interface BaseCondition { - condition: string; -} - -export interface NumericStateCondition extends BaseCondition { - condition: "numeric_state"; - entity?: string; - below?: string | number; - above?: string | number; -} - -export interface StateCondition extends BaseCondition { - condition: "state"; - entity?: string; - state?: string | string[]; - state_not?: string | string[]; -} - -export interface ScreenCondition extends BaseCondition { - condition: "screen"; - media_query?: string; -} - -export interface UserCondition extends BaseCondition { - condition: "user"; - users?: string[]; -} - -export interface OrCondition extends BaseCondition { - condition: "or"; - conditions?: Condition[]; -} - -export interface AndCondition extends BaseCondition { - condition: "and"; - conditions?: Condition[]; -} - -function getValueFromEntityId(hass: HomeAssistant, value: string): string { - if (isValidEntityId(value) && hass.states[value]) { - return hass.states[value]?.state; - } - return value; -} - -function checkStateCondition( - condition: StateCondition | LegacyCondition, - hass: HomeAssistant -) { - const state = - condition.entity && hass.states[condition.entity] - ? hass.states[condition.entity].state - : UNAVAILABLE; - let value = condition.state ?? condition.state_not; - - // Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now) - if (typeof value === "string") { - value = getValueFromEntityId(hass, value); - } - if (Array.isArray(value)) { - value = value.map((val) => getValueFromEntityId(hass, val)); - } - - return condition.state != null - ? ensureArray(value).includes(state) - : !ensureArray(value).includes(state); -} - -function checkStateNumericCondition( - condition: NumericStateCondition, - hass: HomeAssistant -) { - const state = (condition.entity ? hass.states[condition.entity] : undefined) - ?.state; - let above = condition.above; - let below = condition.below; - - // Handle entity_id, UI should be updated for conditionnal card (filters does not have UI for now) - if (typeof above === "string") { - above = getValueFromEntityId(hass, above) as string; - } - if (typeof below === "string") { - below = getValueFromEntityId(hass, below) as string; - } - - const numericState = Number(state); - const numericAbove = Number(above); - const numericBelow = Number(below); - - if (isNaN(numericState)) { - return false; - } - - return ( - (condition.above == null || - isNaN(numericAbove) || - numericAbove < numericState) && - (condition.below == null || - isNaN(numericBelow) || - numericBelow > numericState) - ); -} - -function checkScreenCondition(condition: ScreenCondition, _: HomeAssistant) { - return condition.media_query - ? matchMedia(condition.media_query).matches - : false; -} - -function checkUserCondition(condition: UserCondition, hass: HomeAssistant) { - return condition.users && hass.user?.id - ? condition.users.includes(hass.user.id) - : false; -} - -function checkAndCondition(condition: AndCondition, hass: HomeAssistant) { - if (!condition.conditions) return true; - return checkConditionsMet(condition.conditions, hass); -} - -function checkOrCondition(condition: OrCondition, hass: HomeAssistant) { - if (!condition.conditions) return true; - return condition.conditions.some((c) => checkConditionsMet([c], hass)); -} - /** * Return the result of applying conditions * @param conditions conditions to apply @@ -150,32 +21,25 @@ function checkOrCondition(condition: OrCondition, hass: HomeAssistant) { * @returns true if conditions are respected */ export function checkConditionsMet( - conditions: (Condition | LegacyCondition)[], + conditions: (LovelaceCondition | LegacyCondition)[], hass: HomeAssistant ): boolean { return conditions.every((c) => { if ("condition" in c) { - switch (c.condition) { - case "screen": - return checkScreenCondition(c, hass); - case "user": - return checkUserCondition(c, hass); - case "numeric_state": - return checkStateNumericCondition(c, hass); - case "and": - return checkAndCondition(c, hass); - case "or": - return checkOrCondition(c, hass); - default: - return checkStateCondition(c, hass); - } + return checkCondition(c, hass); } - return checkStateCondition(c, hass); + return checkCondition( + { + condition: "state", + ...c, + }, + hass + ); }); } export function extractConditionEntityIds( - conditions: Condition[] + conditions: LovelaceCondition[] ): Set { const entityIds: Set = new Set(); for (const condition of conditions) { @@ -211,61 +75,22 @@ export function extractConditionEntityIds( return entityIds; } -function validateStateCondition(condition: StateCondition | LegacyCondition) { - return ( - condition.entity != null && - (condition.state != null || condition.state_not != null) - ); -} - -function validateScreenCondition(condition: ScreenCondition) { - return condition.media_query != null; -} - -function validateUserCondition(condition: UserCondition) { - return condition.users != null; -} - -function validateAndCondition(condition: AndCondition) { - return condition.conditions != null; -} - -function validateOrCondition(condition: OrCondition) { - return condition.conditions != null; -} - -function validateNumericStateCondition(condition: NumericStateCondition) { - return ( - condition.entity != null && - (condition.above != null || condition.below != null) - ); -} /** * Validate the conditions config for the UI * @param conditions conditions to apply * @returns true if conditions are validated */ export function validateConditionalConfig( - conditions: (Condition | LegacyCondition)[] + conditions: (LovelaceCondition | LegacyCondition)[] ): boolean { return conditions.every((c) => { if ("condition" in c) { - switch (c.condition) { - case "screen": - return validateScreenCondition(c); - case "user": - return validateUserCondition(c); - case "numeric_state": - return validateNumericStateCondition(c); - case "and": - return validateAndCondition(c); - case "or": - return validateOrCondition(c); - default: - return validateStateCondition(c); - } + return validateCondition(c); } - return validateStateCondition(c); + return validateCondition({ + condition: "state", + ...c, + }); }); } @@ -276,9 +101,9 @@ export function validateConditionalConfig( * @returns a new condition with entity id */ export function addEntityToCondition( - condition: Condition, + condition: LovelaceCondition, entityId: string -): Condition { +): LovelaceCondition { if ("conditions" in condition && condition.conditions) { return { ...condition, diff --git a/src/panels/lovelace/editor/conditions/ha-card-condition-editor.ts b/src/panels/lovelace/editor/conditions/ha-card-condition-editor.ts index f4f0e0e718..90520af2b5 100644 --- a/src/panels/lovelace/editor/conditions/ha-card-condition-editor.ts +++ b/src/panels/lovelace/editor/conditions/ha-card-condition-editor.ts @@ -19,9 +19,9 @@ import "../../../../components/ha-yaml-editor"; import { showAlertDialog } from "../../../../dialogs/generic/show-dialog-box"; import { haStyle } from "../../../../resources/styles"; import type { HomeAssistant } from "../../../../types"; +import { LovelaceCondition } from "../../common/conditions/types"; import { ICON_CONDITION } from "../../common/icon-condition"; import { - Condition, LegacyCondition, checkConditionsMet, validateConditionalConfig, @@ -32,7 +32,9 @@ import type { LovelaceConditionEditorConstructor } from "./types"; export class HaCardConditionEditor extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) condition!: Condition | LegacyCondition; + @property({ attribute: false }) condition!: + | LovelaceCondition + | LegacyCondition; @state() public _yamlMode = false; @@ -40,7 +42,7 @@ export class HaCardConditionEditor extends LitElement { @state() public _uiWarnings: string[] = []; - @state() _condition?: Condition; + @state() _condition?: LovelaceCondition; @state() private _testingResult?: boolean; diff --git a/src/panels/lovelace/editor/conditions/ha-card-conditions-editor.ts b/src/panels/lovelace/editor/conditions/ha-card-conditions-editor.ts index 125d715bb9..5cb07d97f4 100644 --- a/src/panels/lovelace/editor/conditions/ha-card-conditions-editor.ts +++ b/src/panels/lovelace/editor/conditions/ha-card-conditions-editor.ts @@ -16,17 +16,18 @@ import "../../../../components/ha-list-item"; import type { HaSelect } from "../../../../components/ha-select"; import "../../../../components/ha-svg-icon"; import type { HomeAssistant } from "../../../../types"; +import { LovelaceCondition } from "../../common/conditions/types"; import { ICON_CONDITION } from "../../common/icon-condition"; -import { Condition, LegacyCondition } from "../../common/validate-condition"; +import { LegacyCondition } from "../../common/validate-condition"; import "./ha-card-condition-editor"; import type { HaCardConditionEditor } from "./ha-card-condition-editor"; import { LovelaceConditionEditorConstructor } from "./types"; +import "./types/ha-card-condition-and"; import "./types/ha-card-condition-numeric_state"; +import "./types/ha-card-condition-or"; import "./types/ha-card-condition-screen"; import "./types/ha-card-condition-state"; import "./types/ha-card-condition-user"; -import "./types/ha-card-condition-or"; -import "./types/ha-card-condition-and"; const UI_CONDITION = [ "numeric_state", @@ -35,14 +36,14 @@ const UI_CONDITION = [ "user", "and", "or", -] as const satisfies readonly Condition["condition"][]; +] as const satisfies readonly LovelaceCondition["condition"][]; @customElement("ha-card-conditions-editor") export class HaCardConditionsEditor extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public conditions!: ( - | Condition + | LovelaceCondition | LegacyCondition )[]; @@ -138,7 +139,7 @@ export class HaCardConditionsEditor extends LitElement { private _addCondition(ev: CustomEvent): void { const condition = (ev.currentTarget as HaSelect).items[ev.detail.index] - .value as Condition["condition"]; + .value as LovelaceCondition["condition"]; const conditions = [...this.conditions]; const elClass = customElements.get(`ha-card-condition-${condition}`) as diff --git a/src/panels/lovelace/editor/conditions/types/ha-card-condition-and.ts b/src/panels/lovelace/editor/conditions/types/ha-card-condition-and.ts index a228145160..fb015625e4 100644 --- a/src/panels/lovelace/editor/conditions/types/ha-card-condition-and.ts +++ b/src/panels/lovelace/editor/conditions/types/ha-card-condition-and.ts @@ -5,10 +5,9 @@ import { fireEvent } from "../../../../../common/dom/fire_event"; import "../../../../../components/ha-form/ha-form"; import type { HomeAssistant } from "../../../../../types"; import { - AndCondition, - Condition, - StateCondition, -} from "../../../common/validate-condition"; + LovelaceAndCondition, + LovelaceCondition, +} from "../../../common/conditions/types"; import "../ha-card-conditions-editor"; const andConditionStruct = object({ @@ -20,15 +19,15 @@ const andConditionStruct = object({ export class HaCardConditionNumericAnd extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public condition!: AndCondition; + @property({ attribute: false }) public condition!: LovelaceAndCondition; @property({ type: Boolean }) public disabled = false; - public static get defaultConfig(): AndCondition { + public static get defaultConfig(): LovelaceAndCondition { return { condition: "and", conditions: [] }; } - protected static validateUIConfig(condition: StateCondition) { + protected static validateUIConfig(condition: LovelaceAndCondition) { return assert(condition, andConditionStruct); } @@ -46,7 +45,7 @@ export class HaCardConditionNumericAnd extends LitElement { private _valueChanged(ev: CustomEvent): void { ev.stopPropagation(); - const conditions = ev.detail.value as Condition[]; + const conditions = ev.detail.value as LovelaceCondition[]; const condition = { ...this.condition, conditions, diff --git a/src/panels/lovelace/editor/conditions/types/ha-card-condition-numeric_state.ts b/src/panels/lovelace/editor/conditions/types/ha-card-condition-numeric_state.ts index ff33d6352c..4d4c6cc17e 100644 --- a/src/panels/lovelace/editor/conditions/types/ha-card-condition-numeric_state.ts +++ b/src/panels/lovelace/editor/conditions/types/ha-card-condition-numeric_state.ts @@ -8,10 +8,7 @@ import "../../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../../components/ha-form/types"; import { HaFormSchema } from "../../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../../types"; -import { - NumericStateCondition, - StateCondition, -} from "../../../common/validate-condition"; +import { LovelaceNumericStateCondition } from "../../../common/conditions/types"; const numericStateConditionStruct = object({ condition: literal("numeric_state"), @@ -24,15 +21,16 @@ const numericStateConditionStruct = object({ export class HaCardConditionNumericState extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public condition!: NumericStateCondition; + @property({ attribute: false }) + public condition!: LovelaceNumericStateCondition; @property({ type: Boolean }) public disabled = false; - public static get defaultConfig(): NumericStateCondition { + public static get defaultConfig(): LovelaceNumericStateCondition { return { condition: "numeric_state", entity: "" }; } - protected static validateUIConfig(condition: StateCondition) { + protected static validateUIConfig(condition: LovelaceNumericStateCondition) { return assert(condition, numericStateConditionStruct); } @@ -88,7 +86,7 @@ export class HaCardConditionNumericState extends LitElement { private _valueChanged(ev: CustomEvent): void { ev.stopPropagation(); - const condition = ev.detail.value as NumericStateCondition; + const condition = ev.detail.value as LovelaceNumericStateCondition; fireEvent(this, "value-changed", { value: condition }); } diff --git a/src/panels/lovelace/editor/conditions/types/ha-card-condition-or.ts b/src/panels/lovelace/editor/conditions/types/ha-card-condition-or.ts index d9fdfc87a5..c0f58d2269 100644 --- a/src/panels/lovelace/editor/conditions/types/ha-card-condition-or.ts +++ b/src/panels/lovelace/editor/conditions/types/ha-card-condition-or.ts @@ -5,10 +5,9 @@ import { fireEvent } from "../../../../../common/dom/fire_event"; import "../../../../../components/ha-form/ha-form"; import type { HomeAssistant } from "../../../../../types"; import { - Condition, - OrCondition, - StateCondition, -} from "../../../common/validate-condition"; + LovelaceCondition, + LovelaceOrCondition, +} from "../../../common/conditions/types"; import "../ha-card-conditions-editor"; const orConditionStruct = object({ @@ -20,15 +19,15 @@ const orConditionStruct = object({ export class HaCardConditionOr extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public condition!: OrCondition; + @property({ attribute: false }) public condition!: LovelaceOrCondition; @property({ type: Boolean }) public disabled = false; - public static get defaultConfig(): OrCondition { + public static get defaultConfig(): LovelaceOrCondition { return { condition: "or", conditions: [] }; } - protected static validateUIConfig(condition: StateCondition) { + protected static validateUIConfig(condition: LovelaceOrCondition) { return assert(condition, orConditionStruct); } @@ -46,7 +45,7 @@ export class HaCardConditionOr extends LitElement { private _valueChanged(ev: CustomEvent): void { ev.stopPropagation(); - const conditions = ev.detail.value as Condition[]; + const conditions = ev.detail.value as LovelaceCondition[]; const condition = { ...this.condition, conditions, diff --git a/src/panels/lovelace/editor/conditions/types/ha-card-condition-screen.ts b/src/panels/lovelace/editor/conditions/types/ha-card-condition-screen.ts index cd341562e2..d28462e0c5 100644 --- a/src/panels/lovelace/editor/conditions/types/ha-card-condition-screen.ts +++ b/src/panels/lovelace/editor/conditions/types/ha-card-condition-screen.ts @@ -8,7 +8,7 @@ import "../../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../../components/ha-form/types"; import { HaFormSchema } from "../../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../../types"; -import { ScreenCondition } from "../../../common/validate-condition"; +import { LovelaceScreenCondition } from "../../../common/conditions/types"; const BREAKPOINT_VALUES = [0, 768, 1024, 1280, Infinity]; const BREAKPOINTS = ["mobile", "tablet", "desktop", "wide"] as const; @@ -95,16 +95,16 @@ type ScreenConditionData = { export class HaCardConditionScreen extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public condition!: ScreenCondition; + @property({ attribute: false }) public condition!: LovelaceScreenCondition; @property({ type: Boolean }) public disabled = false; - public static get defaultConfig(): ScreenCondition { + public static get defaultConfig(): LovelaceScreenCondition { return { condition: "screen", media_query: "" }; } protected static validateUIConfig( - condition: ScreenCondition, + condition: LovelaceScreenCondition, hass: HomeAssistant ) { const valid = @@ -174,7 +174,7 @@ export class HaCardConditionScreen extends LitElement { const { breakpoints } = data; - const condition: ScreenCondition = { + const condition: LovelaceScreenCondition = { condition: "screen", media_query: mediaQueryMap.get(computeBreakpointsKey(breakpoints)) ?? "", }; diff --git a/src/panels/lovelace/editor/conditions/types/ha-card-condition-state.ts b/src/panels/lovelace/editor/conditions/types/ha-card-condition-state.ts index e0594af3f6..bc90f1bd7c 100644 --- a/src/panels/lovelace/editor/conditions/types/ha-card-condition-state.ts +++ b/src/panels/lovelace/editor/conditions/types/ha-card-condition-state.ts @@ -8,7 +8,7 @@ import "../../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../../components/ha-form/types"; import { HaFormSchema } from "../../../../../components/ha-form/types"; import type { HomeAssistant } from "../../../../../types"; -import { StateCondition } from "../../../common/validate-condition"; +import { LovelaceStateCondition } from "../../../common/conditions/types"; const stateConditionStruct = object({ condition: literal("state"), @@ -28,15 +28,15 @@ type StateConditionData = { export class HaCardConditionState extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public condition!: StateCondition; + @property({ attribute: false }) public condition!: LovelaceStateCondition; @property({ type: Boolean }) public disabled = false; - public static get defaultConfig(): StateCondition { + public static get defaultConfig(): LovelaceStateCondition { return { condition: "state", entity: "", state: "" }; } - protected static validateUIConfig(condition: StateCondition) { + protected static validateUIConfig(condition: LovelaceStateCondition) { return assert(condition, stateConditionStruct); } @@ -124,7 +124,7 @@ export class HaCardConditionState extends LitElement { const { invert, state, condition: _, ...content } = data; - const condition: StateCondition = { + const condition: LovelaceStateCondition = { condition: "state", ...content, state: invert === "false" ? state ?? "" : undefined, diff --git a/src/panels/lovelace/editor/conditions/types/ha-card-condition-user.ts b/src/panels/lovelace/editor/conditions/types/ha-card-condition-user.ts index 68dfc63b67..b7dc35bac8 100644 --- a/src/panels/lovelace/editor/conditions/types/ha-card-condition-user.ts +++ b/src/panels/lovelace/editor/conditions/types/ha-card-condition-user.ts @@ -10,7 +10,7 @@ import "../../../../../components/ha-switch"; import "../../../../../components/user/ha-user-badge"; import { User, fetchUsers } from "../../../../../data/user"; import type { HomeAssistant } from "../../../../../types"; -import { UserCondition } from "../../../common/validate-condition"; +import { LovelaceUserCondition } from "../../../common/conditions/types"; const userConditionStruct = object({ condition: literal("user"), @@ -21,17 +21,17 @@ const userConditionStruct = object({ export class HaCardConditionUser extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; - @property({ attribute: false }) public condition!: UserCondition; + @property({ attribute: false }) public condition!: LovelaceUserCondition; @property({ type: Boolean }) public disabled = false; - public static get defaultConfig(): UserCondition { + public static get defaultConfig(): LovelaceUserCondition { return { condition: "user", users: [] }; } @state() private _users: User[] = []; - protected static validateUIConfig(condition: UserCondition) { + protected static validateUIConfig(condition: LovelaceUserCondition) { return assert(condition, userConditionStruct); } @@ -95,7 +95,7 @@ export class HaCardConditionUser extends LitElement { users = users.filter((user) => user !== userId); } - const condition: UserCondition = { + const condition: LovelaceUserCondition = { ...this.condition, users, };