* Split up SunLightSettings

* Renames

* factor out SunEvents

* more renames

* rewrite

* rewrite more

* simpler

* refactor

* refact

* raise

* refact

* rename

* move method

* clean

* Move to new module 'sun.py'

* make sun independent of HA

* rename

* Move to webapp/homeassistant_util_color.py

* Rework app

* Add link

* new plotting

* app changes

* fix tests

* test clean

* tz fixes

* fix

* use sed

* verbose

* fix tz

* fix

* tiem
This commit is contained in:
Bas Nijholt 2023-08-08 14:31:17 -07:00 • committed by GitHub
commit f8e7880a96
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 1745 additions and 625 deletions

View file

@ -0,0 +1,209 @@
import pytest
from custom_components.adaptive_lighting.color_and_brightness import (
SunEvents,
SUN_EVENT_SUNRISE,
SUN_EVENT_NOON,
)
import datetime as dt
from astral import LocationInfo
from astral.location import Location
import zoneinfo
# Create a mock astral_location object
location = Location(LocationInfo())
LAT_LONG_TZS = [
(52.379189, 4.899431, "Europe/Amsterdam"),
(32.87336, -117.22743, "US/Pacific"),
(60, 50, "GMT"),
(60, 50, "UTC"),
]
@pytest.fixture(params=LAT_LONG_TZS)
def tzinfo_and_location(request):
lat, long, timezone = request.param
tzinfo = zoneinfo.ZoneInfo(timezone)
location = Location(
LocationInfo(
name="name",
region="region",
timezone=timezone,
latitude=lat,
longitude=long,
)
)
return tzinfo, location
def test_replace_time(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
new_time = dt.time(5, 30)
datetime = dt.datetime(2022, 1, 1)
replaced_time_utc = sun_events._replace_time(datetime.date(), new_time)
assert replaced_time_utc.astimezone(tzinfo).time() == new_time
def test_sunrise_without_offset(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
date = dt.datetime(2022, 1, 1).date()
result = sun_events.sunrise(date)
assert result == location.sunrise(date)
def test_sun_position_no_fixed_sunset_and_sunrise(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
date = dt.datetime(2022, 1, 1).date()
sunset = location.sunset(date)
position = sun_events.sun_position(sunset)
assert position == 0
sunrise = location.sunrise(date)
position = sun_events.sun_position(sunrise)
assert position == 0
noon = location.noon(date)
position = sun_events.sun_position(noon)
assert position == 1
midnight = location.midnight(date)
position = sun_events.sun_position(midnight)
assert position == -1
def test_sun_position_fixed_sunset_and_sunrise(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=dt.time(6, 0),
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=dt.time(18, 0),
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
date = dt.datetime(2022, 1, 1).date()
sunset = sun_events.sunset(date)
position = sun_events.sun_position(sunset)
assert position == 0
sunrise = sun_events.sunrise(date)
position = sun_events.sun_position(sunrise)
assert position == 0
noon, midnight = sun_events.noon_and_midnight(date)
position = sun_events.sun_position(noon)
assert position == 1
position = sun_events.sun_position(midnight)
assert position == -1
def test_noon_and_midnight(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
date = dt.datetime(2022, 1, 1)
noon, midnight = sun_events.noon_and_midnight(date)
assert noon == location.noon(date)
assert midnight == location.midnight(date)
def test_sun_events(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
date = dt.datetime(2022, 1, 1)
events = sun_events.sun_events(date)
assert len(events) == 4
assert (SUN_EVENT_SUNRISE, location.sunrise(date).timestamp()) in events
def test_prev_and_next_events(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
datetime = dt.datetime(2022, 1, 1, 10, 0)
after_sunrise = sun_events.sunrise(datetime.date()) + dt.timedelta(hours=1)
prev_event, next_event = sun_events.prev_and_next_events(after_sunrise)
assert prev_event[0] == SUN_EVENT_SUNRISE
assert next_event[0] == SUN_EVENT_NOON
def test_closest_event(tzinfo_and_location):
tzinfo, location = tzinfo_and_location
sun_events = SunEvents(
name="test",
astral_location=location,
sunrise_time=None,
min_sunrise_time=None,
max_sunrise_time=None,
sunset_time=None,
min_sunset_time=None,
max_sunset_time=None,
timezone=tzinfo,
)
datetime = dt.datetime(2022, 1, 1, 6, 0)
sunrise = sun_events.sunrise(datetime.date())
event_name, ts = sun_events.closest_event(sunrise)
assert event_name == SUN_EVENT_SUNRISE
assert ts == location.sunrise(sunrise.date()).timestamp()

View file

@ -100,8 +100,8 @@ from custom_components.adaptive_lighting.switch import (
AdaptiveLightingManager,
is_our_context,
is_our_context_id,
lerp_color_hsv,
)
from custom_components.adaptive_lighting.color_and_brightness import lerp_color_hsv
_LOGGER = logging.getLogger(__name__)
@ -394,6 +394,7 @@ async def test_adaptive_lighting_time_zones_and_sun_settings(
min_color_temp = switch._sun_light_settings.min_color_temp
sunset = SUNSET.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE).astimezone(dt_util.UTC)
before_sunset = sunset - datetime.timedelta(hours=1)
after_sunset = sunset + datetime.timedelta(hours=1)
sunrise = SUNRISE.replace(tzinfo=dt_util.DEFAULT_TIME_ZONE).astimezone(dt_util.UTC)
@ -401,7 +402,10 @@ async def test_adaptive_lighting_time_zones_and_sun_settings(
after_sunrise = sunrise + datetime.timedelta(hours=1)
async def patch_time_and_update(time):
with patch("homeassistant.util.dt.utcnow", return_value=time):
with patch(
"custom_components.adaptive_lighting.color_and_brightness.utcnow",
return_value=time,
):
await switch._update_attrs_and_maybe_adapt_lights(context=context)
await hass.async_block_till_done()
@ -490,7 +494,10 @@ async def test_light_settings(hass):
context = switch.create_context("test") # needs to be passed to update method
async def patch_time_and_get_updated_states(time):
with patch("homeassistant.util.dt.utcnow", return_value=time):
with patch(
"custom_components.adaptive_lighting.color_and_brightness.utcnow",
return_value=time,
):
await switch._update_attrs_and_maybe_adapt_lights(
context=context, transition=0, force=True
)
@ -1818,7 +1825,10 @@ async def test_adapt_until_sleep_and_rgb_colors(hass):
after_sunrise = sunrise + datetime.timedelta(hours=1)
async def patch_time_and_update(time):
with patch("homeassistant.util.dt.utcnow", return_value=time):
with patch(
"custom_components.adaptive_lighting.color_and_brightness.utcnow",
return_value=time,
):
await switch._update_attrs_and_maybe_adapt_lights(context=context)
await hass.async_block_till_done()
@ -2072,7 +2082,10 @@ async def test_brightness_mode(hass, brightness_mode, dark, light):
return abs(a - b) < 0.01
async def patch_time_and_update(time):
with patch("homeassistant.util.dt.utcnow", return_value=time):
with patch(
"custom_components.adaptive_lighting.color_and_brightness.utcnow",
return_value=time,
):
await switch._update_attrs_and_maybe_adapt_lights(context=context)
await hass.async_block_till_done()