49 lines
2.0 KiB
TypeScript
49 lines
2.0 KiB
TypeScript
import { z } from 'zod';
|
|
|
|
import {
|
|
checkStateMatchField,
|
|
stateBaseSchema,
|
|
stateMatchValueSchema,
|
|
} from '../../common/state';
|
|
import { conditionBaseSchema } from '../base';
|
|
import { entityConditionBaseSchema } from './entity-base';
|
|
|
|
// https://www.home-assistant.io/dashboards/conditional/#state
|
|
export const stateConditionSchema = entityConditionBaseSchema
|
|
.extend(conditionBaseSchema.shape)
|
|
.extend(stateBaseSchema.shape)
|
|
.extend({
|
|
// If `condition` is omitted a state condition is assumed (picture-elements form).
|
|
condition: z.literal('state').optional(),
|
|
|
|
// Without `attribute` these are string/list state matchers (enforced by the
|
|
// `superRefine` below); with `attribute` they compare raw against the
|
|
// attribute value, so any type is accepted.
|
|
//
|
|
// `state` is common to both of Home Assistant's condition dialects;
|
|
// `state_not` is only present in HA's picture-elements dialect (not the
|
|
// automation dialect), but respected in both usecases in this card.
|
|
// https://www.home-assistant.io/dashboards/picture-elements/#conditional-element
|
|
state: stateMatchValueSchema,
|
|
state_not: stateMatchValueSchema,
|
|
|
|
// How a list of entities is combined: `all` (the default) requires every
|
|
// entity to match, `any` requires at least one.
|
|
// https://www.home-assistant.io/docs/scripts/conditions/#state-condition
|
|
match: z.enum(['all', 'any']).optional(),
|
|
})
|
|
// A state condition is not useful without either `state` or `state_not` to
|
|
// test against.
|
|
.refine(
|
|
(data) => data.state !== undefined || data.state_not !== undefined,
|
|
'A `state` condition requires `state` or `state_not`',
|
|
)
|
|
// Without `attribute`, the match fields keep HA's string/list form.
|
|
.superRefine((data, ctx) => {
|
|
if (data.attribute !== undefined) {
|
|
return;
|
|
}
|
|
checkStateMatchField(ctx, 'state', data.state, { nullable: false });
|
|
checkStateMatchField(ctx, 'state_not', data.state_not, { nullable: false });
|
|
});
|