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:
- Click Add in the grid toolbar
- Configure the schedule (see sections below)
- 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
- Navigate to System > Attributes
- Create variable attribute:
System Target: variableTarget ID: 0Name: wake_timeValue: 07:00Type: 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:
- Update variable value
- All schedules using that variable adjust automatically
- No schedule reconfiguration needed
Example Use Cases:
- Wake time (differs weekday/weekend)
- Bedtime
- Meal times
- Work start/end times
- Gym schedule
Best Practices
-
Descriptive Names: Clearly indicate schedule purpose
-
Documentation: Use description field extensively
-
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
-
Overlap Consideration: Avoid conflicting schedules
- Don't schedule opposite actions close together
- Use calendar view to identify conflicts
-
Time Buffers: Include time between opposing actions
- Don't turn lights off immediately after turning on
- Allow equipment warm-up time
-
Seasonal Review: Review and adjust schedules seasonally
-
Variable Updates: Update location variables when system moves
-
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:
- Tag schedules with custom attribute
- Macro: "Enable Vacation Mode"
- Disables all tagged schedules
- Enables vacation schedules (random lights)
- 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:
- Enabled: Schedule is enabled
- Macro Enabled: Target macro is enabled
- Date Range: Current date within start/end range
- Cron Pattern: Cron pattern is valid
- Time Zone: System time zone is correct
- System Time: Server time is accurate
- Logs: Check scheduler logs
Wrong Execution Time
Check:
- Time Zone: Verify system time zone setting
- Cron Pattern: Review pattern (use cron validator)
- Variable Value: If using variable, check variable value
- Daylight Saving: Consider DST transitions
- Server Time: Verify server clock is accurate
Variable Schedule Not Working
Check:
- Variable Exists: Variable is created in system
- Variable Type: Variable is date/time type
- Variable Value: Variable has valid time value
- Syntax: Rule syntax correct:
[$variable_name] - Offset Format: Offset uses minutes (not hours)
Calendar Not Showing Schedule
Check:
- Schedule Enabled: Only enabled schedules shown
- Date Range: Schedule active for viewed month
- Cron Pattern: Pattern results in executions during month
- 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:
- Verify
geo_latitudeandgeo_longitudeare correct - Check
timezoneattribute matches location - Ensure server time/date is accurate
Not Executing:
- Verify variable exists:
[$sunset] - Check calculation isn't failing (logs)
- Confirm location attributes set
Best Practices
-
Use Variables for Astronomical:
[$sunset]instead of fixed times -
Buffer Times: Add offsets for gradual transitions
[$sunset]-30for lights before dark[$sunrise]+30for shades after light
-
Seasonal Dates: Use date ranges for seasonal schedules
-
Testing: Create test schedule with near-future time, verify execution, then delete
-
Overlap Avoidance: Space schedules 5-10 minutes apart
-
Maintenance Windows: Schedule maintenance during low-use times
-
Notification Buffer: Don't schedule notifications during sleep hours
-
Calendar Review: Monthly review of calendar for conflicts
Related Documentation
- Macros - Creating macros to schedule
- Schedule Exceptions - Holiday / vacation / seasonal overrides
- Triggers - Event-based automation alternative
- Attributes - Creating time variables