Last active
December 17, 2025 04:52
-
-
Save ConnorGriffin/2e6646bd7295ce06122ee0fe447eee05 to your computer and use it in GitHub Desktop.
HomeAssistant Plot for Brightness Curve
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
| from datetime import datetime, timedelta | |
| import matplotlib.pyplot as plt | |
| def brightness_at_time(t, sunrise, sunset, | |
| pre_sunrise=120, morning_ramp=90, | |
| pre_sunset=60, evening_ramp=240, | |
| min_brightness=20, max_brightness=100): | |
| # Adjusted ramp times | |
| ramp_up_start = sunrise - timedelta(minutes=pre_sunrise) | |
| ramp_up_end = ramp_up_start + timedelta(minutes=morning_ramp) | |
| ramp_down_start = sunset - timedelta(minutes=pre_sunset) | |
| ramp_down_end = ramp_down_start + timedelta(minutes=evening_ramp) | |
| if ramp_up_start <= t < ramp_up_end: | |
| ramp = (t - ramp_up_start).total_seconds() / (morning_ramp*60) | |
| return int(min_brightness + ramp * (max_brightness - min_brightness)) | |
| elif ramp_up_end <= t < ramp_down_start: | |
| return max_brightness | |
| elif ramp_down_start <= t < ramp_down_end: | |
| ramp = (t - ramp_down_start).total_seconds() / (evening_ramp*60) | |
| return int(max_brightness - ramp * (max_brightness - min_brightness)) | |
| else: | |
| return min_brightness | |
| # Sunrise and sunset | |
| sunrise = datetime.strptime("07:23", "%H:%M") | |
| sunset = datetime.strptime("17:23", "%H:%M") | |
| # Ramp offsets/durations | |
| pre_sunrise = 120 | |
| morning_ramp = 150 | |
| pre_sunset = 30 | |
| evening_ramp = 330 | |
| min_brightness = 20 | |
| max_brightness = 100 | |
| # Calculate key times | |
| morning_start = sunrise - timedelta(minutes=pre_sunrise) | |
| morning_end = morning_start + timedelta(minutes=morning_ramp) | |
| evening_start = sunset - timedelta(minutes=pre_sunset) | |
| evening_end = evening_start + timedelta(minutes=evening_ramp) | |
| # Generate times | |
| times = [morning_start.replace(hour=0, minute=0) + timedelta(minutes=i) for i in range(0, 24*60, 5)] | |
| brightness_values = [brightness_at_time(t, sunrise, sunset, | |
| pre_sunrise=pre_sunrise, morning_ramp=morning_ramp, | |
| pre_sunset=pre_sunset, evening_ramp=evening_ramp, | |
| min_brightness=min_brightness, max_brightness=max_brightness) | |
| for t in times] | |
| # Plot | |
| plt.figure(figsize=(15,8)) | |
| plt.plot(times, brightness_values, label="Brightness") | |
| # Add padding for annotations | |
| plt.ylim(min_brightness - 5, max_brightness + 15) # extra space above max | |
| # Annotate sunrise/sunset | |
| plt.axvline(sunrise, color='orange', linestyle='--', label="Sunrise") | |
| plt.axvline(sunset, color='red', linestyle='--', label="Sunset") | |
| # Annotate ramp min/max points | |
| for t_point, label_text in [ | |
| (morning_start, f"Morning min {morning_start.strftime('%H:%M')}"), | |
| (morning_end, f"Morning max {morning_end.strftime('%H:%M')}"), | |
| (evening_start, f"Evening max {evening_start.strftime('%H:%M')}"), | |
| (evening_end, f"Evening min {evening_end.strftime('%H:%M')}") | |
| ]: | |
| brightness = brightness_at_time(t_point, sunrise, sunset, | |
| pre_sunrise=pre_sunrise, morning_ramp=morning_ramp, | |
| pre_sunset=pre_sunset, evening_ramp=evening_ramp, | |
| min_brightness=min_brightness, max_brightness=max_brightness) | |
| plt.scatter(t_point, brightness, color='blue') | |
| plt.text(t_point, brightness + 5, label_text, rotation=45, fontsize=9) | |
| plt.xlabel("Time") | |
| plt.ylabel("Brightness") | |
| plt.title("Light Brightness Over the Day with Key Points") | |
| plt.xticks(rotation=45) | |
| plt.grid(True) | |
| plt.legend() | |
| plt.show() | |
| # Jinja code for HA in use as a templated value for brightness_pct: | |
| {# Force sunrise/sunset times onto today's date #} | |
| {% set sr = today_at((state_attr('sun.sun', 'next_rising') | as_datetime | as_local).strftime('%H:%M')) %} | |
| {% set ss = today_at((state_attr('sun.sun', 'next_setting') | as_datetime | as_local).strftime('%H:%M')) %} | |
| {# Ramp settings #} | |
| {% set pre_sunrise = 120 %} {# minutes before sunrise to start ramp up #} | |
| {% set morning_ramp = 150 %} {# ramp duration in minutes #} | |
| {% set pre_sunset = 30 %} {# minutes before sunset to start ramp down #} | |
| {% set evening_ramp = 360 %} {# ramp duration in minutes #} | |
| {% set min_brightness = 20 %} | |
| {% set max_brightness = 100 %} | |
| {% set t = now() %} | |
| {# Compute ramp start/end times #} | |
| {% set ramp_up_start = sr - timedelta(minutes=pre_sunrise) %} | |
| {% set ramp_up_end = ramp_up_start + timedelta(minutes=morning_ramp) %} | |
| {% set ramp_down_start = ss - timedelta(minutes=pre_sunset) %} | |
| {% set ramp_down_end = ramp_down_start + timedelta(minutes=evening_ramp) %} | |
| {# Determine brightness #} | |
| {% if ramp_up_start <= t < ramp_up_end %} | |
| {{ (min_brightness + ((t - ramp_up_start).total_seconds() / (morning_ramp*60)) * (max_brightness - min_brightness)) | int }} | |
| {% elif ramp_up_end <= t < ramp_down_start %} | |
| {{ max_brightness }} | |
| {% elif ramp_down_start <= t < ramp_down_end %} | |
| {{ (max_brightness - ((t - ramp_down_start).total_seconds() / (evening_ramp*60)) * (max_brightness - min_brightness)) | int }} | |
| {% else %} | |
| {{ min_brightness }} | |
| {% endif %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment