Something went wrong. Try again.
nixos/home-manager config
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103"""Apply OpenRGB lighting for the current time of day.
Takes the path to a JSON file holding the hardware.rgb options."""
import jsonimport mathimport subprocessimport sysfrom datetime import datetime, timezone
def sun_elevation(latitude, longitude, now): """Return the sun's elevation and its elevation at solar noon, in degrees, using the NOAA approximation.""" hour = now.hour + now.minute / 60 + now.second / 3600 g = 2 * math.pi / 365 * (now.timetuple().tm_yday - 1 + (hour - 12) / 24) declination = ( 0.006918 - 0.399912 * math.cos(g) + 0.070257 * math.sin(g) - 0.006758 * math.cos(2 * g) + 0.000907 * math.sin(2 * g) - 0.002697 * math.cos(3 * g) + 0.00148 * math.sin(3 * g) ) equation_of_time = 229.18 * ( 0.000075 + 0.001868 * math.cos(g) - 0.032077 * math.sin(g) - 0.014615 * math.cos(2 * g) - 0.040849 * math.sin(2 * g) ) solar_minutes = hour * 60 + equation_of_time + 4 * longitude hour_angle = math.radians(solar_minutes / 4 - 180) lat = math.radians(latitude) elevation = math.asin( math.sin(lat) * math.sin(declination) + math.cos(lat) * math.cos(declination) * math.cos(hour_angle) ) noon = 90 - abs(latitude - math.degrees(declination)) return math.degrees(elevation), noon
def parse(color): return [int(color[i:i + 2], 16) for i in (0, 2, 4)]
def mix(night, day, t): return [round(n + (d - n) * t) for n, d in zip(night, day)]
def scale(color, balance): return [round(c * b / 255) for c, b in zip(color, balance)]
def hex_color(color): return "".join(f"{c:02X}" for c in color)
def in_off_hours(off_hours, hour): start, end = off_hours["start"], off_hours["end"] if start <= end: return start <= hour < end return hour >= start or hour < end
def main(): with open(sys.argv[1]) as f: cfg = json.load(f)
color = parse(cfg["color"]) daylight = cfg["daylight"] if daylight is not None: # Fraction of the way from the horizon to today's highest point elevation, noon = sun_elevation( daylight["latitude"], daylight["longitude"], datetime.now(timezone.utc), ) t = min(max(elevation / noon, 0), 1) color = mix(color, parse(daylight["color"]), t)
off_hours = cfg["offHours"] if off_hours is not None and in_off_hours(off_hours, datetime.now().hour): color = [0, 0, 0]
mode = ["--mode", cfg["mode"], "--color"] args = [cfg["openrgb"], "--noautoconnect"] if not cfg["devices"]: args += mode + [hex_color(color)] for name, device in cfg["devices"].items(): args += ["--device", name] for zone, size in device["zoneSizes"].items(): args += ["--zone", zone, "--size", str(size)] balanced = scale(color, parse(device["whiteBalance"])) args += mode + [hex_color(balanced)]
subprocess.run(args, check=True)
main()