#!/usr/bin/env bash set -euo pipefail CONF="${XDG_CONFIG_HOME:-$HOME/.config}/hyprsunset/config" STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/hyprsunset" LOG_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/hyprsunset" AUTO_FILE="$STATE_DIR/auto" # "1" = automation ON, "0" = OFF TEMP_FILE="$STATE_DIR/temp" # last manual/night temp persisted MODE_FILE="$STATE_DIR/mode" # "day" or "night" mkdir -p "$STATE_DIR" "$LOG_DIR" # Defaults LAT="52.5200"; LON="13.4050" TEMP_DAY=6500; TEMP_NIGHT=3800 RAMP_DOWN_MIN=45; RAMP_UP_MIN=35 STEP_K=100 FALLBACK_SUNSET="20:30"; FALLBACK_SUNRISE="06:30" # Load config [ -r "$CONF" ] && source "$CONF" cmd() { hyprctl dispatch exec "$1" >/dev/null 2>&1 || true; } start_hyprsunset() { local t="$1" echo -n "$t" > "$TEMP_FILE" cmd "hyprsunset -t $t" } stop_hyprsunset() { cmd "hyprsunset -x" pkill -x hyprsunset >/dev/null 2>&1 || true } # Compute ramp steps between a and b over minutes, step size STEP_K ramp_between() { local from="$1" to="$2" minutes="$3" local step="${STEP_K}" local delta=$(( to - from )) local sign=1 (( delta < 0 )) && sign=-1 local steps=$(( (delta*sign + step - 1) / step )) # ceil [ "$steps" -lt 1 ] && steps=1 local sleep_s=$(( (minutes*60) / steps )) local t="$from" for ((i=1;i<=steps;i++)); do t=$(( from + sign*i*step )) # clamp (( sign == 1 && t > to )) && t="$to" (( sign == -1 && t < to )) && t="$to" start_hyprsunset "$t" sleep "$sleep_s" done } now_hhmm() { date +%H:%M; } sec_until() { # returns seconds until HH:MM tomorrow/ today local target="$1" local now_s=$(date +%s) local tgt_s=$(date -d "$(date +%F) $target" +%s) if (( tgt_s <= now_s )); then tgt_s=$(( tgt_s + 86400 )) fi echo $(( tgt_s - now_s )) } have_sunwait() { command -v sunwait >/dev/null 2>&1; } # Initialize state defaults if missing [ -r "$AUTO_FILE" ] || echo -n "1" > "$AUTO_FILE" # default: automation ON [ -r "$TEMP_FILE" ] || echo -n "$TEMP_NIGHT" > "$TEMP_FILE" [ -r "$MODE_FILE" ] || echo -n "day" > "$MODE_FILE" log() { printf "[hyprsunset] %s\n" "$*" >&2; } while :; do # If automation is OFF, just sleep and retry if [ "$(cat "$AUTO_FILE" 2>/dev/null || echo 1)" != "1" ]; then sleep 30 continue fi if have_sunwait; then # Use sunwait to block until the next event # Decide current solar state quickly # sunwait 'day' exits 0 if sun is up; 'night' if down if sunwait day "$LAT" "$LON" >/dev/null 2>&1; then echo -n "day" > "$MODE_FILE" # Wait for sunset, then ramp down log "waiting for SUNSET via sunwait…" sunwait set "$LAT" "$LON" >/dev/null 2>&1 [ "$(cat "$AUTO_FILE")" = "1" ] || continue log "SUNSET reached → ramp down ${TEMP_DAY}→${TEMP_NIGHT} over ${RAMP_DOWN_MIN}m" ramp_between "$TEMP_DAY" "$TEMP_NIGHT" "$RAMP_DOWN_MIN" echo -n "night" > "$MODE_FILE" # Stay in night until sunrise log "waiting for SUNRISE via sunwait…" sunwait rise "$LAT" "$LON" >/dev/null 2>&1 [ "$(cat "$AUTO_FILE")" = "1" ] || continue log "SUNRISE reached → ramp up ${TEMP_NIGHT}→${TEMP_DAY} over ${RAMP_UP_MIN}m" ramp_between "$TEMP_NIGHT" "$TEMP_DAY" "$RAMP_UP_MIN" echo -n "day" > "$MODE_FILE" else echo -n "night" > "$MODE_FILE" # We are in night → ramp to night if not already, then wait sunrise log "night now → ensure at night temp, then wait SUNRISE" start_hyprsunset "$TEMP_NIGHT" sunwait rise "$LAT" "$LON" >/dev/null 2>&1 [ "$(cat "$AUTO_FILE")" = "1" ] || continue log "SUNRISE → ramp up ${TEMP_NIGHT}→${TEMP_DAY} over ${RAMP_UP_MIN}m" ramp_between "$TEMP_NIGHT" "$TEMP_DAY" "$RAMP_UP_MIN" echo -n "day" > "$MODE_FILE" fi else # Fallback fixed schedule cur="$(now_hhmm)" # If day now (before fallback sunset), wait sunset if [[ "$cur" < "$FALLBACK_SUNSET" && "$cur" > "$FALLBACK_SUNRISE" ]]; then echo -n "day" > "$MODE_FILE" secs=$(sec_until "$FALLBACK_SUNSET") log "fallback: waiting $secs s until sunset ${FALLBACK_SUNSET}" sleep "$secs" [ "$(cat "$AUTO_FILE")" = "1" ] || continue ramp_between "$TEMP_DAY" "$TEMP_NIGHT" "$RAMP_DOWN_MIN" echo -n "night" > "$MODE_FILE" else echo -n "night" > "$MODE_FILE" secs=$(sec_until "$FALLBACK_SUNRISE") log "fallback: waiting $secs s until sunrise ${FALLBACK_SUNRISE}" sleep "$secs" [ "$(cat "$AUTO_FILE")" = "1" ] || continue ramp_between "$TEMP_NIGHT" "$TEMP_DAY" "$RAMP_UP_MIN" echo -n "day" > "$MODE_FILE" fi fi done