Add scheduled power on / off via Wake-on-LAN and ATX - #1537
Open
0xfacade wants to merge 6 commits into
Open
Conversation
Describes a recurring power action as a weekday set plus a wall-clock time in an IANA timezone, and renders it to the 6-field crontab format the jiggler already uses. Storing the schedule structurally rather than as a raw crontab lets the UI offer a weekday/time picker and lets both ends render it consistently. The model lives in internal/ and has no dependency on the device runtime, so its rules can be unit tested on any platform. The root kvm package cannot: its only test file is gated behind linux && arm, and adding an untagged one there would force the test binary to link the ARM native libs on an x86 CI runner. Wake-on-LAN is restricted to powering on, since a magic packet cannot do anything else. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Locks down the format contract with gocron: a crontab we generate but the library rejects would silently disable a schedule at runtime. Also asserts the TZ= prefix is honoured rather than ignored, which is what makes per-schedule timezones work at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Wires the schedule model to gocron and to the two power methods, and
persists schedules in the device config.
Two details worth calling out:
- The scheduler uses its own gocron instance. rpcSetJigglerConfig removes
every job on the jiggler's scheduler, which would silently drop all
power schedules if the two shared one.
- ATX actions consult the power LED before pressing, so a "power on"
schedule can't toggle an already-running host off.
Disabled schedules are kept in the config but get no job, which is how
temporarily disabling one is implemented.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Registers getPowerSchedules/setPowerSchedules and starts the scheduler at boot. Writes replace the whole list and are validated before they are applied or persisted, so a rejected payload leaves the running schedule untouched. Timezone options reuse the existing getTimezones handler. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Source-locale strings only; other locales fall back until translated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adds a Scheduler settings page listing every schedule with a checkbox for temporarily disabling one without deleting it, a next-run line, and an inline add/edit form. The form derives its action options from the selected method, so Wake-on-LAN offers only "power on" and the ATX method is disabled outright unless the ATX extension is active. The MAC picker is populated from the saved Wake-on-LAN devices with a custom-MAC fallback; the address is copied onto the schedule rather than referenced, so deleting a saved device cannot leave a schedule pointing at nothing. Next-run labels compare wall-clock fields inside the schedule's own timezone instead of converting to absolute time. This keeps the label DST-safe to compute without a date library; it is display-only, as the actual firing is gocron's job. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Florian Behrens seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
0xfacade
commented
Jul 26, 2026
| LocalAuthMode string `json:"localAuthMode"` //TODO: fix it with migration | ||
| LocalLoopbackOnly bool `json:"local_loopback_only"` | ||
| WakeOnLanDevices []WakeOnLanDevice `json:"wake_on_lan_devices"` | ||
| PowerSchedules []powersched.Schedule `json:"power_schedules"` |
Author
There was a problem hiding this comment.
I suppose here it would make sense to use a shorter reference so that the diff becomes smaller.
Author
|
Let me know if this is something you are interested in merging, then I'll review the LLM generated code very carefully and in detail (or close the PR if you are not interested). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No existing issue.
Summary
I needed the ability to turn on a power-hungry home server on a schedule (and I don't have another device that could trigger it via MQTT), so I added a settings page that allows defining schedules to turn the host on and off.
Features:
This was entirely coded by Claude Code with Opus 5, but I'll review it thoroughly if there is interest to merge this (I am a SWE). I did not find a policy regarding LLM contributions - if I missed it and such contributions are not welcome, my apologies! I've deployed this to my device and it appears to work fine. I'll keep it running for a while and repeat back on the reliability.
Screenshots:
Checklist
make test_e2elocally and passed (mostly - currently don't have a guest that reads mouse events - can follow up if you'll consider merging this)Closes #<issue-number>)