Add weekdays to time trigger

This commit is contained in:
Franck Nijhof 2025-06-25 11:55:44 +00:00
parent f90eb4fee0
commit 26b528c80e
No known key found for this signature in database
GPG Key ID: AB33ADACE7101952
4 changed files with 92 additions and 18 deletions

View File

@ -169,6 +169,7 @@ export interface TagTrigger extends BaseTrigger {
export interface TimeTrigger extends BaseTrigger { export interface TimeTrigger extends BaseTrigger {
trigger: "time"; trigger: "time";
at: string | { entity_id: string; offset?: string }; at: string | { entity_id: string; offset?: string };
weekday?: string | string[];
} }
export interface TemplateTrigger extends BaseTrigger { export interface TemplateTrigger extends BaseTrigger {

View File

@ -400,9 +400,25 @@ const tryDescribeTrigger = (
return `${entityStr}${offsetStr}`; return `${entityStr}${offsetStr}`;
}); });
return hass.localize(`${triggerTranslationBaseKey}.time.description.full`, { // Handle weekday information if present
time: formatListWithOrs(hass.locale, result), let weekdayStr = "";
}); if (trigger.weekday) {
const weekdayArray = ensureArray(trigger.weekday);
if (weekdayArray.length > 0) {
const localizedDays = weekdayArray.map((day) =>
hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.weekdays.${day}` as any
)
);
weekdayStr = ` on ${formatListWithOrs(hass.locale, localizedDays)}`;
}
}
return (
hass.localize(`${triggerTranslationBaseKey}.time.description.full`, {
time: formatListWithOrs(hass.locale, result),
}) + weekdayStr
);
} }
// Time Pattern Trigger // Time Pattern Trigger

View File

@ -2,11 +2,13 @@ import type { PropertyValues } from "lit";
import { html, LitElement, nothing } from "lit"; import { html, LitElement, nothing } from "lit";
import { customElement, property, state } from "lit/decorators"; import { customElement, property, state } from "lit/decorators";
import memoizeOne from "memoize-one"; import memoizeOne from "memoize-one";
import { firstWeekdayIndex } from "../../../../../common/datetime/first_weekday";
import { fireEvent } from "../../../../../common/dom/fire_event"; import { fireEvent } from "../../../../../common/dom/fire_event";
import type { LocalizeFunc } from "../../../../../common/translations/localize"; import type { LocalizeFunc } from "../../../../../common/translations/localize";
import "../../../../../components/ha-form/ha-form"; import "../../../../../components/ha-form/ha-form";
import type { SchemaUnion } from "../../../../../components/ha-form/types"; import type { SchemaUnion } from "../../../../../components/ha-form/types";
import type { TimeTrigger } from "../../../../../data/automation"; import type { TimeTrigger } from "../../../../../data/automation";
import type { FrontendLocaleData } from "../../../../../data/translation";
import type { HomeAssistant } from "../../../../../types"; import type { HomeAssistant } from "../../../../../types";
import type { TriggerElement } from "../ha-automation-trigger-row"; import type { TriggerElement } from "../ha-automation-trigger-row";
import { computeDomain } from "../../../../../common/entity/compute_domain"; import { computeDomain } from "../../../../../common/entity/compute_domain";
@ -14,6 +16,7 @@ import { computeDomain } from "../../../../../common/entity/compute_domain";
const MODE_TIME = "time"; const MODE_TIME = "time";
const MODE_ENTITY = "entity"; const MODE_ENTITY = "entity";
const VALID_DOMAINS = ["sensor", "input_datetime"]; const VALID_DOMAINS = ["sensor", "input_datetime"];
const DAYS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] as const;
@customElement("ha-automation-trigger-time") @customElement("ha-automation-trigger-time")
export class HaTimeTrigger extends LitElement implements TriggerElement { export class HaTimeTrigger extends LitElement implements TriggerElement {
@ -35,9 +38,14 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
private _schema = memoizeOne( private _schema = memoizeOne(
( (
localize: LocalizeFunc, localize: LocalizeFunc,
locale: FrontendLocaleData,
inputMode: typeof MODE_TIME | typeof MODE_ENTITY inputMode: typeof MODE_TIME | typeof MODE_ENTITY
) => ) => {
[ const dayIndex = firstWeekdayIndex(locale);
const sortedDays = DAYS.slice(dayIndex, DAYS.length).concat(
DAYS.slice(0, dayIndex)
);
return [
{ {
name: "mode", name: "mode",
type: "select", type: "select",
@ -73,7 +81,21 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
}, },
{ name: "offset", selector: { text: {} } }, { name: "offset", selector: { text: {} } },
] as const)), ] as const)),
] as const {
type: "multi_select",
name: "weekday",
options: sortedDays.map(
(day) =>
[
day,
localize(
`ui.panel.config.automation.editor.triggers.type.time.weekdays.${day}`
),
] as const
),
},
] as const;
}
); );
public willUpdate(changedProperties: PropertyValues) { public willUpdate(changedProperties: PropertyValues) {
@ -95,12 +117,14 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
inputMode: undefined | typeof MODE_ENTITY | typeof MODE_TIME, inputMode: undefined | typeof MODE_ENTITY | typeof MODE_TIME,
at: at:
| string | string
| { entity_id: string | undefined; offset?: string | undefined } | { entity_id: string | undefined; offset?: string | undefined },
weekday: string | string[] | undefined
): { ): {
mode: typeof MODE_TIME | typeof MODE_ENTITY; mode: typeof MODE_TIME | typeof MODE_ENTITY;
entity: string | undefined; entity: string | undefined;
time: string | undefined; time: string | undefined;
offset: string | undefined; offset: string | undefined;
weekday: string | string[] | undefined;
} => { } => {
const entity = const entity =
typeof at === "object" typeof at === "object"
@ -116,6 +140,7 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
entity, entity,
time, time,
offset, offset,
weekday,
}; };
} }
); );
@ -127,8 +152,12 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
return nothing; return nothing;
} }
const data = this._data(this._inputMode, at); const data = this._data(this._inputMode, at, this.trigger.weekday);
const schema = this._schema(this.hass.localize, data.mode); const schema = this._schema(
this.hass.localize,
this.hass.locale,
data.mode
);
return html` return html`
<ha-form <ha-form
@ -146,22 +175,36 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
ev.stopPropagation(); ev.stopPropagation();
const newValue = { ...ev.detail.value }; const newValue = { ...ev.detail.value };
this._inputMode = newValue.mode; this._inputMode = newValue.mode;
const weekday = newValue.weekday;
delete newValue.weekday;
if (newValue.mode === MODE_TIME) { if (newValue.mode === MODE_TIME) {
delete newValue.entity; delete newValue.entity;
delete newValue.offset; delete newValue.offset;
} else { } else {
delete newValue.time; delete newValue.time;
} }
const triggerUpdate: TimeTrigger = {
...this.trigger,
at: newValue.offset
? {
entity_id: newValue.entity,
offset: newValue.offset,
}
: newValue.entity || newValue.time,
};
// Only include weekday if it has a value
if (weekday && weekday.length > 0) {
triggerUpdate.weekday = weekday;
} else {
delete triggerUpdate.weekday;
}
fireEvent(this, "value-changed", { fireEvent(this, "value-changed", {
value: { value: triggerUpdate,
...this.trigger,
at: newValue.offset
? {
entity_id: newValue.entity,
offset: newValue.offset,
}
: newValue.entity || newValue.time,
},
}); });
} }
@ -173,6 +216,10 @@ export class HaTimeTrigger extends LitElement implements TriggerElement {
return this.hass.localize( return this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.at` `ui.panel.config.automation.editor.triggers.type.time.at`
); );
case "weekday":
return this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.weekday`
);
} }
return this.hass.localize( return this.hass.localize(
`ui.panel.config.automation.editor.triggers.type.time.${schema.name}` `ui.panel.config.automation.editor.triggers.type.time.${schema.name}`

View File

@ -3951,6 +3951,16 @@
"entity": "Entity with timestamp", "entity": "Entity with timestamp",
"offset_by": "offset by {offset}", "offset_by": "offset by {offset}",
"mode": "Mode", "mode": "Mode",
"weekday": "Weekdays",
"weekdays": {
"mon": "Monday",
"tue": "Tuesday",
"wed": "Wednesday",
"thu": "Thursday",
"fri": "Friday",
"sat": "Saturday",
"sun": "Sunday"
},
"description": { "description": {
"picker": "At a specific time, or on a specific date.", "picker": "At a specific time, or on a specific date.",
"full": "When the time is equal to {time}" "full": "When the time is equal to {time}"