diff --git a/README.md b/README.md index 617c8d41..57ea2739 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,68 @@ -# hass-circadian_lighting -Circadian Lighting custom component for Home Assistant +# Circadian Lighting [[Home Assistant](https://www.home-assistant.io/) Component] +## Stay healthier and sleep better by syncing your lights with natural daylight to maintain your circadian rhythm! + +![Circadian Light Rhythm|690x287](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/5/f/5fe7a780e9f8905fea4d1cbb66cdbe35858a6e36.jpg) + +Circadian Lighting slowly synchronizes your color changing lights with the regular naturally occuring color temperature of the sky throughout the day. This gives your environment a more natural feel, with cooler hues during the midday and warmer tints near twilight and dawn. + +In addition, Circadian Lighting can set your lights to a nice cool white at 1% in “Sleep” mode, which is far brighter than starlight but won’t reset your circadian rhythm or break down too much rhodopsin in your eyes. + + +
Expand for articles explaining the benefits of maintaining a natural Circadian rhythm + +* [Circadian Rhythms - National Institute of General Medical Sciences](https://www.nigms.nih.gov/Education/Pages/Factsheet_CircadianRhythms.aspx) +* [Circadian Rhythms Linked to Aging and Well-Being | Psychology Today](https://www.psychologytoday.com/us/blog/the-athletes-way/201306/circadian-rhythms-linked-aging-and-well-being) +* [Maintaining a daily rhythm is important for mental health, study suggests - CNN](https://www.cnn.com/2018/05/15/health/circadian-rhythm-mood-disorder-study/index.html) +* [How Nobel Winning Circadian Rhythm Research Benefits Pregnancy](https://www.healthypregnancy.com/how-nobel-prize-winning-circadian-rhythms-research-benefits-a-healthy-pregnancy/) +* [Body Clock & Sleep - National Sleep Foundation](https://sleepfoundation.org/sleep-topics/sleep-drive-and-your-body-clock) + +
+ +### Visit the [Wiki](https://github.com/claytonjn/hass-circadian_lighting/wiki) for more information. +
+ +## Basic Installation/Configuration Instructions: + +#### Files - ALL THREE REQUIRED! +* [config/custom_components/circadian_lighting/\_\_init__.py](https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/__init__.py) +* [config/custom_components/circadian_lighting/sensor.py](https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/sensor.py) +* [config/custom_components/circadian_lighting/switch.py](https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/switch.py) + +#### Component Configuration: +```yaml +# Example configuration.yaml entry +circadian_lighting: +``` +[_Advanced Configuration_](https://github.com/claytonjn/hass-circadian_lighting/wiki/Advanced-Configuration#component-configuration-variables) + +#### Switch Configuration: +```yaml +# Example configuration.yaml entry +switch: + - platform: circadian_lighting + lights_ct: + - light.desk + - light.lamp +``` +Switch configuration variables: +* **name** (_Optional_): The name to use when displaying this switch. +* **lights_ct** (_Optional_): array: List of light entities which should be set in mireds. +* **lights_rgb** (_Optional_): array: List of light entities which should be set in RGB. +* **lights_xy** (_Optional_): array: List of light entities which should be set in XY. +* **lights_brightness** (_Optional_): array: List of light entities which should only have brightness adjusted. + +[_Advanced Configuration_](https://github.com/claytonjn/hass-circadian_lighting/wiki/Advanced-Configuration#switch-configuration-variables) + +
+ +### Graphs! +These graphs were generated using the values calculated by the Circadian Lighting sensor/switch(es). + +##### Sun Position: +![cl_percent|690x131](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/6/5/657ff98beb65a94598edeb4bdfd939095db1a22c.PNG) + +##### Color Temperature: +![cl_colortemp|690x129](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/5/9/59e84263cbecd8e428cb08777a0413672c48dfcd.PNG) + +##### Brightness: +![cl_brightness|690x130](https://community-home-assistant-assets.s3.dualstack.us-west-2.amazonaws.com/original/3X/5/8/58ebd994b62a8b1abfb3497a5288d923ff4e2330.PNG) diff --git a/custom_components/circadian_lighting/__init__.py b/custom_components/circadian_lighting/__init__.py index c31e138b..eef94f6a 100644 --- a/custom_components/circadian_lighting/__init__.py +++ b/custom_components/circadian_lighting/__init__.py @@ -35,7 +35,7 @@ import homeassistant.helpers.config_validation as cv from homeassistant.components.light import ( VALID_TRANSITION, ATTR_TRANSITION) from homeassistant.const import ( - CONF_LATITUDE, CONF_LONGITUDE, + CONF_LATITUDE, CONF_LONGITUDE, CONF_ELEVATION, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET) from homeassistant.util import Throttle from homeassistant.helpers.discovery import load_platform @@ -46,10 +46,9 @@ from homeassistant.util.color import ( color_xy_to_hs) from homeassistant.util.dt import utcnow as dt_utcnow, as_local -import astral from datetime import datetime, timedelta -from .const import VERSION +VERSION = '1.0.3' _LOGGER = logging.getLogger(__name__) @@ -81,6 +80,7 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_SUNSET_TIME): cv.time, vol.Optional(CONF_LATITUDE): cv.latitude, vol.Optional(CONF_LONGITUDE): cv.longitude, + vol.Optional(CONF_ELEVATION): float, vol.Optional(CONF_INTERVAL, default=DEFAULT_INTERVAL): cv.positive_int, vol.Optional(ATTR_TRANSITION, default=DEFAULT_INTERVAL): VALID_TRANSITION }), @@ -96,15 +96,9 @@ def setup(hass, config): sunrise_time = conf.get(CONF_SUNRISE_TIME) sunset_time = conf.get(CONF_SUNSET_TIME) - if conf.get(CONF_LATITUDE) is None: - latitude = hass.config.latitude - else: - latitude = conf.get(CONF_LATITUDE) - - if conf.get(CONF_LONGITUDE) is None: - longitude = hass.config.longitude - else: - longitude = conf.get(CONF_LONGITUDE) + latitude = conf.get(CONF_LATITUDE, hass.config.latitude) + longitude = conf.get(CONF_LONGITUDE, hass.config.longitude) + elevation = conf.get(CONF_ELEVATION, hass.config.elevation) load_platform(hass, 'sensor', DOMAIN, {}, config) @@ -113,7 +107,7 @@ def setup(hass, config): cl = CircadianLighting(hass, min_colortemp, max_colortemp, sunrise_offset, sunset_offset, sunrise_time, sunset_time, - latitude, longitude, + latitude, longitude, elevation, interval, transition) hass.data[DATA_CIRCADIAN_LIGHTING] = cl @@ -125,7 +119,7 @@ class CircadianLighting(object): def __init__(self, hass, min_colortemp, max_colortemp, sunrise_offset, sunset_offset, sunrise_time, sunset_time, - latitude, longitude, + latitude, longitude, elevation, interval, transition): self.hass = hass self.data = {} @@ -137,6 +131,7 @@ class CircadianLighting(object): self.data['sunset_time'] = sunset_time self.data['latitude'] = latitude self.data['longitude'] = longitude + self.data['elevation'] = elevation self.data['interval'] = interval self.data['transition'] = transition self.data['percent'] = self.calc_percent() @@ -166,9 +161,14 @@ class CircadianLighting(object): solar_noon = sunrise + (sunset - sunrise)/2 solar_midnight = sunset + ((sunrise + timedelta(days=1)) - sunset)/2 else: + import astral location = astral.Location() + location.name = 'name' + location.region = 'region' location.latitude = self.data['latitude'] location.longitude = self.data['longitude'] + location.elevation = self.data['elevation'] + _LOGGER.debug("Astral location: " + str(location)) if self.data['sunrise_time'] is not None: if date is None: utcdate = dt_utcnow() @@ -199,7 +199,7 @@ class CircadianLighting(object): def calc_percent(self): utcnow = dt_utcnow() now = as_local(utcnow) - today_sun_times = self.get_sunrise_sunset() + today_sun_times = self.get_sunrise_sunset(now) now_seconds = now.timestamp() today_sunrise_seconds = today_sun_times[SUN_EVENT_SUNRISE].timestamp() @@ -207,12 +207,16 @@ class CircadianLighting(object): today_solar_noon_seconds = today_sun_times['solar_noon'].timestamp() today_solar_midnight_seconds = today_sun_times['solar_midnight'].timestamp() + _LOGGER.debug("now: " + str(now) + "\n\n today_sun_times: " + str(today_sun_times)) + if now < today_sun_times[SUN_EVENT_SUNRISE]: yesterday_sun_times = self.get_sunrise_sunset(now - timedelta(days=1)) yesterday_sunrise_seconds = yesterday_sun_times[SUN_EVENT_SUNRISE].timestamp() yesterday_sunset_seconds = yesterday_sun_times[SUN_EVENT_SUNSET].timestamp() yesterday_solar_midnight_seconds = yesterday_sun_times['solar_midnight'].timestamp() + _LOGGER.debug("yesterday_sun_times: " + str(yesterday_sun_times)) + x1 = yesterday_sunset_seconds y1 = 0 @@ -249,6 +253,8 @@ class CircadianLighting(object): x3 = today_sunset_seconds y3 = 0 + _LOGGER.debug("x1: " + str(x1) + "\n\n y1: " + str(y1) + "\n\n x2: " + str(x2) + "\n\n y2: " + str(y2)) + # Generate color temperature parabola from points a1 = -x1**2+x2**2 b1 = -x1+x2 @@ -264,6 +270,8 @@ class CircadianLighting(object): c = y1-a*x1**2-b*x1 percentage = a*now_seconds**2+b*now_seconds+c + _LOGGER.debug("percentage: " + str(percentage)) + return percentage def calc_colortemp(self): diff --git a/custom_components/circadian_lighting/const.py b/custom_components/circadian_lighting/const.py deleted file mode 100644 index 88138c0f..00000000 --- a/custom_components/circadian_lighting/const.py +++ /dev/null @@ -1,3 +0,0 @@ -# coding: utf-8 -"""Constants used by Circadian Lighting components.""" -VERSION = '1.0.0' \ No newline at end of file diff --git a/custom_components/circadian_lighting/sensor.py b/custom_components/circadian_lighting/sensor.py index a3d35045..3395142b 100644 --- a/custom_components/circadian_lighting/sensor.py +++ b/custom_components/circadian_lighting/sensor.py @@ -13,8 +13,6 @@ from homeassistant.helpers.entity import Entity import datetime -from .const import VERSION - _LOGGER = logging.getLogger(__name__) ICON = 'mdi:theme-light-dark' diff --git a/custom_components/circadian_lighting/switch.py b/custom_components/circadian_lighting/switch.py index 4420eba8..380e03fe 100644 --- a/custom_components/circadian_lighting/switch.py +++ b/custom_components/circadian_lighting/switch.py @@ -26,8 +26,6 @@ from homeassistant.util.color import ( color_RGB_to_xy, color_temperature_kelvin_to_mired, color_temperature_to_rgb, color_xy_to_hs) -from .const import VERSION - _LOGGER = logging.getLogger(__name__) ICON = 'mdi:theme-light-dark' diff --git a/custom_updater.json b/custom_updater.json index 2981e5bf..e28e0f86 100644 --- a/custom_updater.json +++ b/custom_updater.json @@ -1,13 +1,12 @@ { "circadian_lighting": { - "updated_at": "2019-04-03", - "version": "1.0.0", + "updated_at": "2019-04-05", + "version": "1.0.3", "local_location": "/custom_components/circadian_lighting/__init__.py", "remote_location": "https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/__init__.py", "visit_repo": "https://github.com/claytonjn/hass-circadian_lighting", "changelog": "https://github.com/claytonjn/hass-circadian_lighting/releases", "resources": [ - "https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/const.py", "https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/sensor.py", "https://raw.githubusercontent.com/claytonjn/hass-circadian_lighting/master/custom_components/circadian_lighting/switch.py" ]