Add support for users and numeric_conditions.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { CurrentUser } from '@dermotduffy/custom-card-helpers';
|
||||
import { HassEntities } from 'home-assistant-js-websocket';
|
||||
import merge from 'lodash-es/merge';
|
||||
import { copyConfig } from '../config-mgmt';
|
||||
@@ -22,6 +23,7 @@ interface ConditionState {
|
||||
triggered?: Set<string>;
|
||||
interaction?: boolean;
|
||||
microphone?: MicrophoneConditionState;
|
||||
user?: CurrentUser;
|
||||
}
|
||||
|
||||
export class ConditionEvaluateRequestEvent extends Event {
|
||||
@@ -174,7 +176,10 @@ export class ConditionsManager {
|
||||
|
||||
const conditions = getAllConditions();
|
||||
this._hasHAStateConditions = conditions.some(
|
||||
(condition) => !!condition.state?.length,
|
||||
(condition) =>
|
||||
!!condition.state?.length ||
|
||||
!!condition.numeric_state?.length ||
|
||||
!!condition.users?.length,
|
||||
);
|
||||
conditions.forEach((condition) => {
|
||||
if (condition.media_query) {
|
||||
@@ -192,7 +197,7 @@ export class ConditionsManager {
|
||||
};
|
||||
this._triggerChange();
|
||||
}
|
||||
|
||||
|
||||
public getState(): ConditionState {
|
||||
return this._state;
|
||||
}
|
||||
@@ -235,11 +240,30 @@ export class ConditionsManager {
|
||||
((!stateTest.state && !stateTest.state_not) ||
|
||||
(stateTest.entity in state.state &&
|
||||
(!stateTest.state ||
|
||||
state.state[stateTest.entity].state === stateTest.state) &&
|
||||
(Array.isArray(stateTest.state)
|
||||
? stateTest.state.includes(state.state[stateTest.entity].state)
|
||||
: stateTest.state === state.state[stateTest.entity].state)) &&
|
||||
(!stateTest.state_not ||
|
||||
state.state[stateTest.entity].state !== stateTest.state_not)));
|
||||
(Array.isArray(stateTest.state_not)
|
||||
? !stateTest.state_not.includes(state.state[stateTest.entity].state)
|
||||
: stateTest.state_not !== state.state[stateTest.entity].state))));
|
||||
}
|
||||
}
|
||||
if (condition.numeric_state?.length) {
|
||||
for (const stateTest of condition.numeric_state) {
|
||||
result &&=
|
||||
!!state.state &&
|
||||
stateTest.entity in state.state &&
|
||||
state.state[stateTest.entity].state !== undefined &&
|
||||
(stateTest.above === undefined ||
|
||||
Number(state.state[stateTest.entity].state) > stateTest.above) &&
|
||||
(stateTest.below === undefined ||
|
||||
Number(state.state[stateTest.entity].state) < stateTest.below);
|
||||
}
|
||||
}
|
||||
if (condition.users?.length) {
|
||||
result &&= !!state.user && condition.users.includes(state.user.id);
|
||||
}
|
||||
if (condition.media_loaded !== undefined) {
|
||||
result &&=
|
||||
state.media_loaded !== undefined &&
|
||||
|
||||
@@ -66,7 +66,10 @@ export class HASSManager {
|
||||
}
|
||||
|
||||
if (this._api.getConditionsManager().hasHAStateConditions()) {
|
||||
this._api.getConditionsManager().setState({ state: this._hass.states });
|
||||
this._api.getConditionsManager().setState({
|
||||
state: this._hass.states,
|
||||
user: this._hass.user,
|
||||
});
|
||||
}
|
||||
|
||||
// Dark mode may depend on HASS.
|
||||
|
||||
+41
-12
@@ -400,20 +400,47 @@ const imageSchema = elementsBaseSchema.extend({
|
||||
aspect_ratio: z.string().optional(),
|
||||
});
|
||||
|
||||
// This state condition is used both for the Picture elements conditional
|
||||
// schema, and also in frigateCardConditionSchema.
|
||||
const stateConditions = z
|
||||
.object({
|
||||
entity: z.string(),
|
||||
state: z.string().optional(),
|
||||
state_not: z.string().optional(),
|
||||
})
|
||||
.array();
|
||||
// https://www.home-assistant.io/dashboards/conditional/#state
|
||||
const stateCondition = z.object({
|
||||
condition: z.literal('state'),
|
||||
entity: z.string(),
|
||||
state: z.string().or(z.string().array()).optional(),
|
||||
state_not: z.string().or(z.string().array()).optional(),
|
||||
});
|
||||
|
||||
// https://www.home-assistant.io/dashboards/conditional/#numeric-state
|
||||
const numericCondition = z.object({
|
||||
condition: z.literal('numeric_state'),
|
||||
entity: z.string(),
|
||||
above: z.number().optional(),
|
||||
below: z.number().optional(),
|
||||
});
|
||||
|
||||
const mediaQuerySchema = z.string();
|
||||
|
||||
// https://www.home-assistant.io/dashboards/conditional/#screen
|
||||
const screenCondition = z.object({
|
||||
condition: z.literal('screen'),
|
||||
media_query: mediaQuerySchema,
|
||||
});
|
||||
|
||||
// https://www.home-assistant.io/dashboards/conditional/#user
|
||||
const usersCondition = z.object({
|
||||
condition: z.literal('user'),
|
||||
users: z.string().array().min(1),
|
||||
});
|
||||
|
||||
const stockCondition = z.union([
|
||||
stateCondition,
|
||||
numericCondition,
|
||||
screenCondition,
|
||||
usersCondition,
|
||||
]);
|
||||
|
||||
// https://www.home-assistant.io/lovelace/picture-elements/#image-element
|
||||
export const conditionalSchema = z.object({
|
||||
type: z.literal('conditional'),
|
||||
conditions: stateConditions,
|
||||
conditions: stockCondition.array(),
|
||||
elements: z.lazy(() => pictureElementsSchema),
|
||||
});
|
||||
|
||||
@@ -501,12 +528,14 @@ export const frigateCardConditionSchema = z.object({
|
||||
expand: z.boolean().optional(),
|
||||
camera: z.string().array().optional(),
|
||||
media_loaded: z.boolean().optional(),
|
||||
state: stateConditions.optional(),
|
||||
media_query: z.string().optional(),
|
||||
state: stateCondition.array().optional(),
|
||||
numeric_state: numericCondition.array().optional(),
|
||||
media_query: mediaQuerySchema.optional(),
|
||||
display_mode: viewDisplayModeSchema.optional(),
|
||||
triggered: z.string().array().optional(),
|
||||
interaction: z.boolean().optional(),
|
||||
microphone: microphoneConditionSchema.optional(),
|
||||
users: z.string().array().optional()
|
||||
});
|
||||
export type FrigateCardCondition = z.infer<typeof frigateCardConditionSchema>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user