feat(nightlight): geo mode — lat/long-computed sunset via wlsunset
All checks were successful
Check / eval (push) Successful in 4m20s

Set BOTH nomarchy.nightlight.latitude/.longitude and the night light
switches backing unit: wlsunset computes sunrise/sunset from the
location daily (the fixed .sunrise/.sunset are ignored;
.temperature feeds the night temp). Everything user-facing is
unchanged — same nomarchy-nightlight toggle script, Waybar moon, and
live-state ExecCondition gate; the unit name is a single let-binding
so all three follow together. Declarative-only on purpose: coordinates
are machine config like the keyboard layout, so home.nix (commented
template example), not a menu writer.

checks.nightlight-geo guards the wiring at pure eval: rendered
wlsunset ExecStart carries the coords + night temperature, the
ExecCondition gate landed on the swapped unit, hyprsunset stays off in
geo mode.

Verification: V1 — nix flake check --no-build exit 0 (evals the new
asserts + option-docs sync); built downstream-template-home (default
hyprsunset path unregressed). V3 pending: visible warm shift at the
location's night + instant toggle/off-persistence on the swapped unit
(HARDWARE-QUEUE § Any machine).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Bernardo Magri
2026-07-11 09:30:52 +01:00
parent 4c656b1e73
commit 4ebd6770ec
9 changed files with 127 additions and 13 deletions

View File

@@ -550,6 +550,48 @@
in
assert ok; pkgs.runCommand "nomarchy-display-profiles" { } "touch $out";
# Night-light geo mode: with BOTH lat/long set the backing unit
# flips hyprsunset → wlsunset (location-computed sunrise/sunset)
# and the live-state ExecCondition gate survives the swap (the
# toggle script's unit= comes from the same let-binding, so the
# gate landing on wlsunset covers the selection logic). Pure
# eval over the rendered HM units — nothing is built. The
# visible warm shift itself stays hardware-tier (HARDWARE-QUEUE),
# exactly like the original night-light full cycle.
nightlight-geo =
let
inherit (nixpkgs) lib;
hm = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [
self.homeModules.nomarchy
{
nomarchy.stateFile = ./templates/downstream/theme-state.json;
nomarchy.nightlight = {
enable = true;
latitude = "52.52";
longitude = "13.40";
};
home = { username = "geo"; homeDirectory = "/home/geo"; };
}
];
};
units = hm.config.systemd.user.services;
exec = toString units.wlsunset.Service.ExecStart;
cond = toString units.wlsunset.Service.ExecCondition;
expect = c: msg: lib.assertMsg c "nightlight-geo: ${msg}";
ok =
expect (lib.hasInfix "52.52" exec && lib.hasInfix "13.40" exec)
"wlsunset ExecStart lacks the configured coordinates: ${exec}"
&& expect (lib.hasInfix "4000" exec)
"wlsunset ExecStart lacks the night temperature: ${exec}"
&& expect (lib.hasInfix "should-start" cond)
"wlsunset lost the live-state ExecCondition gate"
&& expect (!(hm.config.services.hyprsunset.enable or false))
"geo mode must not also run hyprsunset";
in
assert ok; pkgs.runCommand "nomarchy-nightlight-geo" { } "touch $out";
# The low-battery watcher's crossing logic: one toast per downward
# crossing (normal at 25%, critical at 10%), re-armed by charging.
# test_power fakes a battery whose capacity/status we script;