What I built
I run an Orthodox Jewish household. That means twenty-five hours a week, every week, the family doesn't touch electronics, doesn't cook, and doesn't adjust the thermostat without thinking about it. Multiply that by the Jewish holiday calendar, where a holiday can chain into Shabbat for two days straight, and you have a real scheduling problem. The fridge needs to be in Sabbath mode before candle lighting and back to normal at the conclusion of the day. The bedroom AC needs a pre-cooled run that ends before sunset. The living room AC needs to know whether it's a heat wave week or not. None of these can be touched once the time starts.
I built a personal automation stack on top of OpenClaw that handles all of it. The lobster is in charge.
There is a small wrinkle here that I think is a bit funny. Lobsters are not kosher. The mascot of the open source agent platform managing my religiously observant home is, in fact, one of the most explicitly non-kosher animals. The lobster AI has been very gracious about all of that.
How I used OpenClaw
OpenClaw skills are just directories with a SKILL.md and whatever scripts you want the agent to call. That structure made it natural to build each appliance as its own skill and then layer scheduler scripts on top that get triggered by cron jobs not the LLM.
This split matters. The schedulers don't need an LLM in the loop. They need to be deterministic, idempotent, and survive me forgetting they exist. The agent layer is for the times I message OpenClaw on Telegram and ask "is the fridge already in Sabbath mode?" and want a real answer back.
Here are two of the schedulers, with the city ID swapped out so you can drop in your own.
The Shabbat scheduler
This one runs every Friday morning. It pulls candle lighting and havdalah times from Hebcal, then schedules at jobs to flip the fridge into Sabbath mode an hour before candle lighting and back out at it concludes.
pythondef get_shabbat_times():
"""Fetch this week's candle lighting and havdalah times."""
resp = requests.get(HEBCAL_URL, params={
"cfg": "json",
"geonameid": MY_CITY_GEONAMEID,
"M": "on",
}, timeout=15)
resp.raise_for_status()
data = resp.json()
candles = None
havdalah = None
parasha = None
for item in data.get("items", []):
if item.get("category") == "candles" and not candles:
candles = datetime.fromisoformat(item["date"])
elif item.get("category") == "havdalah" and not havdalah:
havdalah = datetime.fromisoformat(item["date"])
elif item.get("category") == "parashat" and not parasha:
parasha = item.get("title", "")
return candles, havdalah, parasha
Then the actual scheduling:
pythonsabbath_on_time = candles - timedelta(hours=1)
schedule_at_job(sabbath_on_time, "on")
schedule_at_job(havdalah, "off")
That's the whole shape of it. Hebcal is the single source of truth for times, the appliance skill is the single source of truth for how to talk to the fridge, and the scheduler just glues them together with at.
The Holiday scheduler
This is the one that took the most thought, because the Jewish holiday calendar is genuinely hostile to naive scheduling. Rosh Hashana is two days. Yom Tov can start as Shabbat ends and run another full day. Passover has a full holiday day with all restrictions on day one, the intermediate days in the middle with no electroni restrictions, and the holiday fully again on the last day.
You can't just toggle the fridge per holiday day. You need to know when the whole continuous Sabbath-mode period actually ends.
So the scheduler walks forward through consecutive holiday days and Shabbat as one block:
pythondef find_end_of_period(start_date, yomtov_dates):
"""Walk forward through consecutive Yom Tov days and Shabbat.
Handles multi-day Yom Tov, Yom Tov flowing into Shabbat,
and Shabbat sandwiched between Yom Tov days."""
current = start_date
while True:
next_day = current + timedelta(days=1)
if next_day in yomtov_dates or next_day.weekday() == 5:
current = next_day
else:
break
return current
The most useful piece, though, is the coordination between schedulers. When a holiday starts as Shabbat is ending, the Shabbat scheduler has already queued an OFF job for the end of Shabbat. If the holiday scheduler runs and just queues its own ON job on top, you get a brief window where the fridge exits Sabbath mode and re-enters it, which defeats the point. So the Yom Tov scheduler clears the conflicting Shabbat job before doing its own work:
pythonif dow == 5: # Saturday: Yom Tov starts motzei Shabbat
log("Yom Tov follows Shabbat, fridge already in sabbath mode")
log("Cancelling Shabbat OFF job so sabbath mode stays on")
clear_existing_jobs("shabbat_scheduler.py")
That one block is the kind of thing working through the full complexity of the calendar introduces you to.
The reminder
Half an hour before candle lighting, OpenClaw sends me a checklist over Telegram. Nothing too complicated, just a quick list:
pythonmessage = (
f"Shabbat Reminder -- {parasha or 'Shabbat Shalom'}\n\n"
f"Candle lighting in 1 hour at {candles_local}.\n"
f"Havdalah at {havdalah_local}.\n\n"
f"Checklist:\n"
f"- Lights\n"
f"- Fridge (SabbathMode)\n"
f"- Door\n"
f"- Plata / hot water"
)
The reminder doesn't take any actions on the appliances. The schedulers already did that. It's a human-in-the-loop check that the things requiring human judgement (the door key, the lights I forgot to switch) actually got handled.
The orchestration layer
Everything is wired together with launchd plists:
kosher-lobster.openclaw.cron.shabbat-scheduler.plist fires every Friday morning
kosher-lobster.openclaw.cron.yomtov-scheduler.plist fires daily
kosher-lobster.openclaw.cron.shabbat-ac.plist and shabbat-sleep.plist handle the AC zones
kosher-lobster.openclaw.cron.shabbat-reminder.plist fires the Telegram message
The AC schedulers are weather-aware. They pull a forecast, checks against a temperature threshold, and only generates ON/OFF blocks if the forecast warrants it. The data model shows the shape:
tsinterface ShabbatPlan {
parasha: string;
candles: string;
havdalah: string;
forecast: {
friday_high_f: number;
saturday_high_f: number;
threshold_f: number;
extreme_heat?: boolean;
};
temp_c: number;
temp_f: number;
blocks: ShabbatBlock[]; // ON/OFF time blocks
status: string; // active | skipped | cancelled
}
A mild Friday in spring? No AC plan generated, no electricity wasted. A heat wave week? Blocks get pre-computed and queued. The scheduler decides; I don't wake up at 5 AM to think about it.
What I learned
The thing I underestimated going in was how much of OpenClaw's value comes from the boundary it draws between agent-driven work and deterministic work. I started by trying to make OpenClaw as the LLM "decide" when to flip the fridge. That was a bad idea. There's no room here for an agent reasoning incorrectly about a calendar edge case.
The right pattern was:
- The scheduler scripts are deterministic, and committable to git
- The skill
SKILL.mdfiles teach the agent how to query state when I ask - The agent never takes scheduled actions on its own; it answers questions and runs explicit commands
OpenClaw's skill structure made that separation easy to maintain because each skill is just a folder. The schedulers live alongside the skills they call, share the same Python environment, and don't require any agent loop to function. If I uninstalled OpenClaw tomorrow the cron jobs would keep firing and the fridge would keep going into Sabbath mode on time. That's the right resilience property for this kind of automation.
The other thing I learned is that the agent shines exactly where the schedulers can't help.
"Is the AC set for this evening?" is a Friday-afternoon question I used to answer by a lot of inquiry into the weather, figuring out what we needed in each room and more. Now I message OpenClaw on Telegram and get the AC schedule shared with me in two seconds.
The schedulers handle the recurring; the agent handles the one-off. Both of those are first-class in OpenClaw and that's why this works.
The lobster, against all expectations, has turned out to be the most observant member of the household. He never forgets the time. He never opens the fridge without checking. He has read more of the Jewish calendar API than any of us.


Top comments (0)