Skip to main content

Macro Schedules

Macro Schedules enable time-based automation by executing macros at specific times, on specific days, or based on astronomical events. This is essential for creating daily routines, seasonal adjustments, and predictable automation.

Overview

The Macro Schedules page provides:

  • Cron-Based Scheduling: Flexible time patterns using cron syntax
  • Variable-Based Scheduling: Tie to sunrise, sunset, or custom variables
  • Date Range Limiting: Seasonal or temporary schedules
  • Calendar Visualization: See when schedules will execute
  • Time Zone Support: Respects system time zone

Viewing Macro Schedules

The main grid displays all configured schedules with the following columns:

  • ID - Unique schedule identifier
  • Name - Internal schedule name
  • Description - Purpose of the schedule
  • Macro - Macro to execute
  • Start Time - Optional start date
  • End Time - Optional end date
  • Rule - Cron pattern or variable reference (read-only in grid; edit via the schedule editor)
  • Enabled - Whether schedule is active

Grid Actions

  • Add - Create a new schedule
  • Edit - Modify an existing schedule
  • Delete - Remove a schedule
  • Reload - Refresh the grid data

Header Actions

  • 📅 View Calendar - Open calendar view showing all schedules

Creating a Schedule

To create a new macro schedule:

  1. Click Add in the grid toolbar
  2. Configure the schedule (see sections below)
  3. Click Save

Schedule Configuration

Basic Information

Name

  • Internal identifier (lowercase_with_underscores)
  • Examples: morning_lights, sunset_shades, weekly_backup

Description

  • Human-readable description
  • Examples: "Turn on morning lights", "Close shades at sunset"
  • Helps document schedule purpose

Enabled

  • Toggle to activate/deactivate schedule
  • Disabled schedules don't execute
  • Configuration preserved

Macro Selection

Macro

  • Select macro to execute on schedule
  • Dropdown of all macros
  • Macro must be enabled
  • When no macro is selected, a + button appears next to the picker. Click it to create a new macro on the fly using the schedule's name (with _2, _3, … appended on collisions, with a prompt to override). The new macro is created enabled, auto-selected, and its step editor opens in a modal so you can fill in steps immediately.

Macro Arguments (optional)

  • JSON object with parameters for macro
  • Example: {"brightness": 75, "color_temp": 3000}
  • See Macros for macro arguments

Time Rule

Defines when the macro executes. Two types:

Cron Pattern

Traditional cron syntax for recurring schedules:

Format:

* * * * *
│ │ │ │ │
│ │ │ │ └─ Day of week (0-6, Sun-Sat)
│ │ │ └─── Month (1-12)
│ │ └───── Day of month (1-31)
│ └─────── Hour (0-23)
└───────── Minute (0-59)

Examples:

Every Day at 7:00 AM:

0 7 * * *

Every Weekday at 6:30 AM:

30 6 * * 1-5

Every Hour:

0 * * * *

Twice Daily (8 AM and 8 PM):

0 8,20 * * *

First of Month at Midnight:

0 0 1 * *

Every 15 Minutes:

*/15 * * * *

Weekends Only at Noon:

0 12 * * 0,6

Describe the Schedule (natural language):

When an Anthropic API key is configured (the AI Assistant is set up), the cron editor shows a Describe the schedule box above the cron fields. Type a plain-English schedule — for example "every weekday at 6:30am", "every 15 minutes", or "the first of each month at midnight" — and click Build Cron. The cron fields below are filled in automatically and a one-line summary of when it runs is shown.

This only works for repeating intervals. One-time dates or sunrise/sunset-relative schedules return a short note explaining they can't be expressed as a cron pattern (use a variable reference for astronomical times). The generated expression is validated before it's applied, and you can always fine-tune it with the cron fields afterward. If no API key is on file, the box is hidden and the editor behaves exactly as before.

Human-Readable Display:

The grid automatically converts cron patterns to readable text:

  • 0 7 * * * → "At 07:00 AM"
  • 30 6 * * 1-5 → "At 06:30 AM, Monday through Friday"
  • 0 */2 * * * → "Every 2 hours"

Variable Reference

Use system variables for dynamic times:

Astronomical Variables:

  • [$sunrise] - Sunrise time
  • [$sunset] - Sunset time
  • [$solar_noon] - Solar noon
  • [$civil_dawn] - Civil dawn
  • [$civil_dusk] - Civil dusk

Custom Variables:

  • Any date/time variable you create
  • Reference with [$variable_name]

Offsets:

  • Before: [$sunset]-30 (30 minutes before sunset)
  • After: [$sunrise]+15 (15 minutes after sunrise)
  • Format: Minutes offset

Examples:

At Sunset:

[$sunset]

30 Minutes Before Sunset:

[$sunset]-30

15 Minutes After Sunrise:

[$sunrise]+15

Variable Wake Time:

[$wake_time]
(where wake_time is a variable set by user or automation)

Date Range

Optionally limit schedule to specific dates:

Start Time (optional)

  • Schedule begins on this date
  • Format: YYYY-MM-DD or date picker
  • Example: 2024-06-01 (summer schedules)

End Time (optional)

  • Schedule ends on this date
  • Format: YYYY-MM-DD or date picker
  • Example: 2024-09-01 (end of summer)

Use Cases:

  • Seasonal schedules (pool heating May-September)
  • Temporary schedules (vacation lighting July 1-14)
  • Event-specific (holiday decorations Nov-Jan)
  • Testing (enable for one week to test)

Open-Ended:

  • Leave both blank: Runs indefinitely
  • Start only: Runs from start date forward
  • End only: Runs until end date

Exceptions (in-editor)

The schedule editor has an Exceptions panel that lists every Schedule Exception attached to the open schedule. Each row is one link with its own action:

  • Skip — suppress this schedule during the exception window
  • Substitute — run a different macro during the window
  • Only During — the schedule fires only while the exception is active

Use the panel to attach existing exceptions or change a link's action/substitute macro inline. To define a new window, jump to Schedule Exceptions. Skipped and substituted firings show up in Run History with the exception name as the reason.

Run History (in-editor)

The schedule editor has a Run History panel that lists every recorded fire of the open schedule. Each row shows started-at, status (success / failed / skipped — skipped fires are gated by start_time / end_time or a disabled target macro), duration, reason, and the dispatched macro.

Clicking a row opens the Cause Chain modal which walks down to the macro that actually ran and any nested macros that followed. Useful for confirming an early-morning schedule actually fired (and what it did) without scanning the activity log.

Retention is governed by the Automation History settings under Data Retention.

Calendar View

The calendar visualization shows when schedules will execute — and, crucially, what each firing will actually do once Schedule Exceptions are applied. The calendar is driven by the same scheduler resolver that runs the schedules, so the preview can never disagree with what really fires.

Opening Calendar

Click 📅 View Calendar button:

  • Calendar opens showing current month
  • All enabled schedules displayed
  • Each schedule color-coded

Calendar Display

Schedule legend:

  • Shows each schedule with its unique color
  • Matches the colored times on the calendar

Status legend (how each firing is rendered):

  • Plain time (e.g. 7:00 AM) — fires normally
  • Struck-through time — the firing is skipped, either by an active exception or because the date is outside the schedule's start/end window
  • Time with ⟳ — a substitute macro runs in place of the scheduled one
  • Shaded "exception window" tag — a day covered by an exception window

Calendar Grid:

  • Days of month, with colored times on days with schedules
  • Hover a time for its schedule name and (for skipped/substituted firings) the reason
  • Hover the shaded tag for the exception name(s) covering that day

Navigation:

  • Previous/Next month arrows
  • Today button to return to current month

Schedule Display on Day:

15 🟡 holiday ← exception window shading
7:00 AM (morning_lights) ← runs
8:00 PM (sunset_shades) ← runs
~~10:30 PM~~ (goodnight) ← skipped by exception
6:30 AM ⟳ (weekday_open) ← substitute macro runs instead

Variable-based schedules ([$sunrise], [$sunset], custom date variables) are rendered from the current variable value rather than the cron forecast, so they appear on every day.

Use Cases

Planning:

  • Visualize schedule conflicts
  • Verify schedules execute at intended times
  • Check seasonal schedule activation

Client Demonstrations:

  • Show clients when automation will run
  • Verify schedule meets expectations
  • Adjust timing based on feedback

Troubleshooting:

  • Verify schedule should have executed on specific date
  • Check for missing executions
  • Validate cron pattern

Cron Pattern Examples

Daily Schedules

Every Day at Specific Time:

0 7 * * * → 7:00 AM daily
0 22 * * * → 10:00 PM daily
30 18 * * * → 6:30 PM daily

Weekly Schedules

Specific Days:

0 9 * * 1 → 9:00 AM every Monday
0 19 * * 5 → 7:00 PM every Friday
0 12 * * 0,6 → Noon every weekend

Weekdays vs. Weekends:

0 6 * * 1-5 → 6:00 AM weekdays
0 9 * * 0,6 → 9:00 AM weekends

Monthly Schedules

Specific Day of Month:

0 0 1 * * → Midnight on 1st of each month
0 12 15 * * → Noon on 15th of each month

Last Day of Month:

0 23 28-31 * * → 11 PM on last days (will only run on last day)

Interval Schedules

Repeated Intervals:

*/5 * * * * → Every 5 minutes
*/30 * * * * → Every 30 minutes
0 */2 * * * → Every 2 hours
0 */6 * * * → Every 6 hours (4 times/day)

Seasonal Schedules

Summer Schedule (June-August):

Cron: 0 20 * * *
Start: 2024-06-01
End: 2024-08-31

Winter Schedule (December-February):

Cron: 0 17 * * *
Start: 2024-12-01
End: 2025-02-28

Complex Patterns

Multiple Times Per Day:

0 6,12,18 * * * → 6 AM, noon, 6 PM

Specific Hours on Specific Days:

0 9-17 * * 1-5 → 9 AM to 5 PM, hourly, weekdays only

Irregular Intervals:

15,45 * * * * → At :15 and :45 of every hour

Astronomical Scheduling

Using sunrise/sunset for natural automation:

Prerequisites

Configure location in System settings:

// Global attributes
geo_latitude: 40.7128 // New York City
geo_longitude: -74.0060
timezone: "America/New_York"

GEM calculates sunrise/sunset based on location and date.

Sunrise/Sunset Variables

Available Variables:

  • [$sunrise] - Sunrise time
  • [$sunset] - Sunset time
  • [$solar_noon] - Solar noon
  • [$civil_dawn] - Civil dawn (sun 6° below horizon)
  • [$civil_dusk] - Civil dusk
  • [$nautical_dawn] - Nautical dawn (sun 12° below horizon)
  • [$nautical_dusk] - Nautical dusk
  • [$astronomical_dawn] - Astronomical dawn (sun 18° below horizon)
  • [$astronomical_dusk] - Astronomical dusk

Offset Examples

Outdoor Lights:

Turn On at Sunset:

Schedule: outdoor_lights_on
Rule: [$sunset]
Macro: outdoor_lights_on

Turn Off at Sunrise:

Schedule: outdoor_lights_off
Rule: [$sunrise]
Macro: outdoor_lights_off

Turn On Before Sunset:

Schedule: early_outdoor_lights
Rule: [$sunset]-30
Macro: outdoor_lights_on
Description: Turn on 30 minutes before sunset

Turn Off After Sunrise:

Schedule: late_outdoor_lights_off
Rule: [$sunrise]+60
Macro: outdoor_lights_off
Description: Turn off 1 hour after sunrise

Wake Up with Sunrise

Schedule: sunrise_wake
Rule: [$sunrise]-15
Macro: gradual_wake_up
Description: Start wake-up routine 15 minutes before sunrise

Automatic Shading

Close Shades Before Peak Sun:

Schedule: close_south_shades
Rule: [$solar_noon]-30
Macro: close_south_facing_shades
Description: Close shades 30 min before peak sun (energy saving)
Start: 2024-05-01 (late spring)
End: 2024-09-30 (early fall)

Custom Variables

Create custom time variables for user-specific schedules:

Creating Time Variables

  1. Navigate to System > Attributes
  2. Create variable attribute:
    System Target: variable
    Target ID: 0
    Name: wake_time
    Value: 07:00
    Type: date

Using in Schedules

Reference in schedule rule:

Schedule: morning_routine
Rule: [$wake_time]
Macro: good_morning
Description: Executes at user's configured wake time

Changing Variables

Users can change wake time without editing schedules:

  1. Update variable value
  2. All schedules using that variable adjust automatically
  3. No schedule reconfiguration needed

Example Use Cases:

  • Wake time (differs weekday/weekend)
  • Bedtime
  • Meal times
  • Work start/end times
  • Gym schedule

Best Practices

  1. Descriptive Names: Clearly indicate schedule purpose

  2. Documentation: Use description field extensively

  3. Testing: Use date range to test new schedules

    • Set start date: today
    • Set end date: tomorrow
    • Test for one day
    • Remove date range when validated
  4. Overlap Consideration: Avoid conflicting schedules

    • Don't schedule opposite actions close together
    • Use calendar view to identify conflicts
  5. Time Buffers: Include time between opposing actions

    • Don't turn lights off immediately after turning on
    • Allow equipment warm-up time
  6. Seasonal Review: Review and adjust schedules seasonally

  7. Variable Updates: Update location variables when system moves

  8. Backup Schedules: Export schedule configuration before changes

Advanced Topics

Dynamic Scheduling

Change schedules programmatically:

// In macro or script
await GemApp.getInstance().updateModel('macro_schedule', scheduleId, {
enabled: true,
rule: '0 18 * * *'
});

Vacation Mode

Disable personal schedules during vacation:

  1. Tag schedules with custom attribute
  2. Macro: "Enable Vacation Mode"
    • Disables all tagged schedules
    • Enables vacation schedules (random lights)
  3. Macro: "Disable Vacation Mode"
    • Re-enables personal schedules
    • Disables vacation schedules

Adaptive Scheduling

Adjust schedule times based on usage:

Example: Bedtime schedule

  • Track when users actually go to bed
  • Store in variable: typical_bedtime
  • Schedule uses: [$typical_bedtime]
  • Learning algorithm updates variable over time

Requires custom implementation.

Troubleshooting

Schedule Not Executing

Check:

  1. Enabled: Schedule is enabled
  2. Macro Enabled: Target macro is enabled
  3. Date Range: Current date within start/end range
  4. Cron Pattern: Cron pattern is valid
  5. Time Zone: System time zone is correct
  6. System Time: Server time is accurate
  7. Logs: Check scheduler logs

Wrong Execution Time

Check:

  1. Time Zone: Verify system time zone setting
  2. Cron Pattern: Review pattern (use cron validator)
  3. Variable Value: If using variable, check variable value
  4. Daylight Saving: Consider DST transitions
  5. Server Time: Verify server clock is accurate

Variable Schedule Not Working

Check:

  1. Variable Exists: Variable is created in system
  2. Variable Type: Variable is date/time type
  3. Variable Value: Variable has valid time value
  4. Syntax: Rule syntax correct: [$variable_name]
  5. Offset Format: Offset uses minutes (not hours)

Calendar Not Showing Schedule

Check:

  1. Schedule Enabled: Only enabled schedules shown
  2. Date Range: Schedule active for viewed month
  3. Cron Pattern: Pattern results in executions during month
  4. Variables: Variable schedules shown on all days (can't predict)

Cron Pattern Reference

Cron Syntax

┌───────── Minute (0-59)
│ ┌─────── Hour (0-23)
│ │ ┌───── Day of month (1-31)
│ │ │ ┌─── Month (1-12)
│ │ │ │ ┌─ Day of week (0-6, Sun-Sat)
│ │ │ │ │
* * * * *

Special Characters

Asterisk (*): Any value

* * * * * → Every minute

Comma (,): Multiple values

0 6,18 * * * → 6 AM and 6 PM

Hyphen (-): Range

0 9 * * 1-5 → 9 AM weekdays

Slash (/): Interval

*/10 * * * * → Every 10 minutes

Testing Cron Patterns

Use online cron validators:

  • crontab.guru
  • crontab-generator.org
  • Or GEM's calendar view

Common Patterns

Daily:

0 7 * * * → 7 AM daily
0 12 * * * → Noon daily
0 22 * * * → 10 PM daily

Weekly:

0 10 * * 1 → 10 AM every Monday
0 9 * * 0 → 9 AM every Sunday

Monthly:

0 0 1 * * → Midnight on 1st of month
0 12 15 * * → Noon on 15th of month

Quarterly:

0 0 1 1,4,7,10 * → Midnight on Jan 1, Apr 1, Jul 1, Oct 1

Yearly:

0 0 1 1 * → Midnight on January 1st
0 9 25 12 * → 9 AM on Christmas

Example Schedules

Morning Routine

Name: morning_wake_up
Description: Gradual wake-up sequence
Macro: good_morning
Rule: 30 6 * * 1-5 (6:30 AM weekdays)
Start: (none)
End: (none)
Enabled: Yes

Evening Lights

Name: sunset_outdoor_lights
Description: Turn on outdoor lights at sunset
Macro: outdoor_lights_on
Rule: [$sunset]
Enabled: Yes

Bedtime

Name: bedtime_routine
Description: Bedtime automation
Macro: goodnight
Rule: 30 22 * * * (10:30 PM daily)
Enabled: Yes

Weekend Late Wake

Name: weekend_wake
Description: Later wake time on weekends
Macro: good_morning
Rule: 0 9 * * 0,6 (9:00 AM Saturday and Sunday)
Enabled: Yes

Seasonal Pool

Name: summer_pool_filter
Description: Run pool filter during summer
Macro: pool_filter_cycle
Rule: 0 10 * * * (10 AM daily)
Start: 2024-05-01
End: 2024-09-30
Enabled: Yes

Filter Change Reminder

Name: quarterly_filter_reminder
Description: HVAC filter change reminder
Macro: send_filter_reminder
Rule: 0 9 1 1,4,7,10 * (9 AM on 1st of Jan, Apr, Jul, Oct)
Enabled: Yes

Astronomical Calculation

Sunrise/sunset times are calculated daily:

Calculation Details

  • Location: Based on geo_latitude and geo_longitude
  • Date: Recalculated each day
  • Accuracy: Within 1-2 minutes of actual sunrise/sunset
  • Algorithm: Uses standard astronomical formulas

Seasonal Variation

Sunrise/sunset times change throughout year:

Summer Solstice (June):

  • Early sunrise (5:30 AM)
  • Late sunset (8:30 PM)

Winter Solstice (December):

  • Late sunrise (7:30 AM)
  • Early sunset (4:30 PM)

Schedules automatically adjust to seasonal changes.

Troubleshooting Astronomical

Wrong Times:

  1. Verify geo_latitude and geo_longitude are correct
  2. Check timezone attribute matches location
  3. Ensure server time/date is accurate

Not Executing:

  1. Verify variable exists: [$sunset]
  2. Check calculation isn't failing (logs)
  3. Confirm location attributes set

Best Practices

  1. Use Variables for Astronomical: [$sunset] instead of fixed times

  2. Buffer Times: Add offsets for gradual transitions

    • [$sunset]-30 for lights before dark
    • [$sunrise]+30 for shades after light
  3. Seasonal Dates: Use date ranges for seasonal schedules

  4. Testing: Create test schedule with near-future time, verify execution, then delete

  5. Overlap Avoidance: Space schedules 5-10 minutes apart

  6. Maintenance Windows: Schedule maintenance during low-use times

  7. Notification Buffer: Don't schedule notifications during sleep hours

  8. Calendar Review: Monthly review of calendar for conflicts