def get_sunrise_sunset(self, date=None): if self.data['sunrise_time'] is not None and self.data[ 'sunset_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) solar_noon = sunrise + (sunset - sunrise) / 2 solar_midnight = sunset + ( (sunrise + timedelta(days=1)) - sunset) / 2 else: location = astral.Location() location.latitude = self.data['latitude'] location.longitude = self.data['longitude'] if self.data['sunrise_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) else: sunrise = location.sunrise(date) if self.data['sunset_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) else: sunset = location.sunset(date) solar_noon = location.solar_noon(date) solar_midnight = location.solar_midnight(date) if self.data['sunrise_offset'] is not None: sunrise = sunrise + self.data['sunrise_offset'] if self.data['sunset_offset'] is not None: sunset = sunset + self.data['sunset_offset'] return { SUN_EVENT_SUNRISE: sunrise, SUN_EVENT_SUNSET: sunset, 'solar_noon': solar_noon, 'solar_midnight': solar_midnight }
async def async_update(self, utcnow=None): """Get the latest data from inverter and update the states.""" if utcnow is None: utcnow = dt_utcnow() now = as_local(utcnow) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) # Prevent errors when data not present at night but retain long term states if start_time <= now <= stop_time or self._device == 'powerflow': await self._data.async_update() if not self._data: _LOGGER.error("Didn't receive data from the inverter") return else: _LOGGER.debug("It's night time for the Fronius inverter") return state = 0 if self._data.latest_data and (self._json_key in self._data.latest_data): if self._device == 'inverter': if self._scope == 'Device': # Read data state = self._data.latest_data[self._json_key]['Value'] elif self._scope == 'System': for item in self._data.latest_data[ self._json_key]['Values']: state = state + self._data.latest_data[ self._json_key]['Values'][item] elif self._device == 'powerflow': # Read data if self._data.latest_data[self._json_key]: state = self._data.latest_data[self._json_key] # convert and round the result if self._json_key == "YEAR_ENERGY" or self._json_key == "TOTAL_ENERGY": if self._units == "MWh": self._state = round(state / 1000000, 2) elif self._units == "kWh": self._state = round(state / 1000, 2) else: self._state = round(state, 2) elif self._json_key == "DAY_ENERGY": self._state = round(state / 1000, 2) else: self._state = round(state, 2) # Prevent these values going to zero if inverter is offline if (self._json_key == "YEAR_ENERGY" or self._json_key == "TOTAL_ENERGY") and state == 0: self._state = None
def available(self, utcnow=None): if utcnow is None: utcnow = dt_utcnow() now = as_local(utcnow) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) _LOGGER.debug("!!! Start Time, Stop Time, Device: {}, {}, {}".format(as_local(start_time), as_local(stop_time), self._device)) return True
def available(self, utcnow=None): if self._always_log: return True if utcnow is None: utcnow = dt_utcnow() now = as_local(utcnow) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) if as_local(start_time) <= now <= as_local(stop_time): _LOGGER.debug("Sensor is running. Start/Stop time: {}, {}".format(as_local(start_time), as_local(stop_time))) return True else: _LOGGER.debug("Sensor is not running. Start/Stop time: {}, {}".format(as_local(start_time), as_local(stop_time))) return False
def available(self, utc_now=None): _LOGGER.debug("Sunset variable: " + self._sunset) if self._sunset == 'False': _LOGGER.debug("Sensor is running. Sunset is disabled") return True if utc_now is None: utc_now = dt_utcnow() now = as_local(utc_now) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) if as_local(start_time) <= now <= as_local(stop_time): _LOGGER.debug("Sensor is running. Start/Stop time: {}, {}".format( as_local(start_time), as_local(stop_time))) return True else: _LOGGER.debug( "Sensor is not running. Start/Stop time: {}, {}".format( as_local(start_time), as_local(stop_time))) return False
async def async_flux_update(self, utcnow=None): """Update all the lights using flux.""" if utcnow is None: utcnow = dt_utcnow() now = as_local(utcnow) sunset = get_astral_event_date(self.hass, SUN_EVENT_SUNSET, now.date()) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) if stop_time <= start_time: # stop_time does not happen in the same day as start_time if start_time < now: # stop time is tomorrow stop_time += datetime.timedelta(days=1) elif now < start_time: # stop_time was yesterday since the new start_time is not reached stop_time -= datetime.timedelta(days=1) if start_time < now < sunset: # Daytime time_state = "day" temp_range = abs(self._start_colortemp - self._sunset_colortemp) day_length = int(sunset.timestamp() - start_time.timestamp()) seconds_from_start = int(now.timestamp() - start_time.timestamp()) percentage_complete = seconds_from_start / day_length temp_offset = temp_range * percentage_complete if self._start_colortemp > self._sunset_colortemp: temp = self._start_colortemp - temp_offset else: temp = self._start_colortemp + temp_offset else: # Night time time_state = "night" if now < stop_time: if stop_time < start_time and stop_time.day == sunset.day: # we need to use yesterday's sunset time sunset_time = sunset - datetime.timedelta(days=1) else: sunset_time = sunset night_length = int(stop_time.timestamp() - sunset_time.timestamp()) seconds_from_sunset = int(now.timestamp() - sunset_time.timestamp()) percentage_complete = seconds_from_sunset / night_length else: percentage_complete = 1 temp_range = abs(self._sunset_colortemp - self._stop_colortemp) temp_offset = temp_range * percentage_complete if self._sunset_colortemp > self._stop_colortemp: temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset rgb = color_temperature_to_rgb(temp) x_val, y_val, b_val = color_RGB_to_xy_brightness(*rgb) brightness = self._brightness if self._brightness else b_val if self._disable_brightness_adjust: brightness = None if self._mode == MODE_XY: await async_set_lights_xy(self.hass, self._lights, x_val, y_val, brightness, self._transition) _LOGGER.debug( "Lights updated to x:%s y:%s brightness:%s, %s%% " "of %s cycle complete at %s", x_val, y_val, brightness, round(percentage_complete * 100), time_state, now, ) elif self._mode == MODE_RGB: await async_set_lights_rgb(self.hass, self._lights, rgb, self._transition) _LOGGER.debug( "Lights updated to rgb:%s, %s%% of %s cycle complete at %s", rgb, round(percentage_complete * 100), time_state, now, ) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) await async_set_lights_temp(self.hass, self._lights, mired, brightness, self._transition) _LOGGER.debug( "Lights updated to mired:%s brightness:%s, %s%% " "of %s cycle complete at %s", mired, brightness, round(percentage_complete * 100), time_state, now, )
def calc_percent(self): utcnow = dt_utcnow() now = as_local(utcnow) _LOGGER.debug("now: " + str(now)) today_sun_times = self.get_sunrise_sunset(now) _LOGGER.debug("today_sun_times: " + str(today_sun_times)) # Convert everything to epoch timestamps for easy calculation now_seconds = now.timestamp() sunrise_seconds = today_sun_times[SUN_EVENT_SUNRISE].timestamp() sunset_seconds = today_sun_times[SUN_EVENT_SUNSET].timestamp() solar_noon_seconds = today_sun_times['solar_noon'].timestamp() solar_midnight_seconds = today_sun_times['solar_midnight'].timestamp() if now < today_sun_times[SUN_EVENT_SUNRISE]: # It's before sunrise (after midnight) # Because it's before sunrise (and after midnight) sunset must have happend yesterday yesterday_sun_times = self.get_sunrise_sunset(now - timedelta(days=1)) _LOGGER.debug("yesterday_sun_times: " + str(yesterday_sun_times)) sunset_seconds = yesterday_sun_times[SUN_EVENT_SUNSET].timestamp() if today_sun_times['solar_midnight'] > today_sun_times[SUN_EVENT_SUNSET] and yesterday_sun_times['solar_midnight'] > yesterday_sun_times[SUN_EVENT_SUNSET]: # Solar midnight is after sunset so use yesterdays's time solar_midnight_seconds = yesterday_sun_times['solar_midnight'].timestamp() elif now > today_sun_times[SUN_EVENT_SUNSET]: # It's after sunset (before midnight) # Because it's after sunset (and before midnight) sunrise should happen tomorrow tomorrow_sun_times = self.get_sunrise_sunset(now + timedelta(days=1)) _LOGGER.debug("tomorrow_sun_times: " + str(tomorrow_sun_times)) sunrise_seconds = tomorrow_sun_times[SUN_EVENT_SUNRISE].timestamp() if today_sun_times['solar_midnight'] < today_sun_times[SUN_EVENT_SUNRISE] and tomorrow_sun_times['solar_midnight'] < tomorrow_sun_times[SUN_EVENT_SUNRISE]: # Solar midnight is before sunrise so use tomorrow's time solar_midnight_seconds = tomorrow_sun_times['solar_midnight'].timestamp() _LOGGER.debug("now_seconds: " + str(now_seconds)) _LOGGER.debug("sunrise_seconds: " + str(sunrise_seconds)) _LOGGER.debug("sunset_seconds: " + str(sunset_seconds)) _LOGGER.debug("solar_midnight_seconds: " + str(solar_midnight_seconds)) _LOGGER.debug("solar_noon_seconds: " + str(solar_noon_seconds)) # Figure out where we are in time so we know which half of the parabola to calculate # We're generating a different sunset-sunrise parabola for before and after solar midnight # because it might not be half way between sunrise and sunset # We're also (obviously) generating a different parabola for sunrise-sunset # sunrise-sunset parabola if now_seconds > sunrise_seconds and now_seconds < sunset_seconds: h = solar_noon_seconds k = 100 # parabola before solar_noon if now_seconds < solar_noon_seconds: x = sunrise_seconds # parabola after solar_noon else: x = sunset_seconds y = 0 # sunset_sunrise parabola elif now_seconds > sunset_seconds and now_seconds < sunrise_seconds: h = solar_midnight_seconds k = -100 # parabola before solar_midnight if now_seconds < solar_midnight_seconds: x = sunset_seconds # parabola after solar_midnight else: x = sunrise_seconds y = 0 a = (y-k)/(h-x)**2 percentage = a*(now_seconds-h)**2+k _LOGGER.debug("h: " + str(h)) _LOGGER.debug("k: " + str(k)) _LOGGER.debug("x: " + str(x)) _LOGGER.debug("y: " + str(y)) _LOGGER.debug("a: " + str(a)) _LOGGER.debug("percentage: " + str(percentage)) return percentage
def get_sunrise_sunset(self, date=None): if self.data['sunrise_time'] is not None and self.data[ 'sunset_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) solar_noon = sunrise + (sunset - sunrise) / 2 solar_midnight = sunset + ( (sunrise + timedelta(days=1)) - sunset) / 2 else: import astral try: location = astral.location.Location() except AttributeError: 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() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data['sunrise_time'].strftime("%H")), minute=int(self.data['sunrise_time'].strftime("%M")), second=int(self.data['sunrise_time'].strftime("%S")), microsecond=int(self.data['sunrise_time'].strftime("%f"))) else: sunrise = location.sunrise(date) if self.data['sunset_time'] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunset = date.replace( hour=int(self.data['sunset_time'].strftime("%H")), minute=int(self.data['sunset_time'].strftime("%M")), second=int(self.data['sunset_time'].strftime("%S")), microsecond=int(self.data['sunset_time'].strftime("%f"))) else: sunset = location.sunset(date) try: solar_noon = location.noon(date) except AttributeError: solar_noon = location.solar_noon(date) try: solar_midnight = location.midnight(date) except AttributeError: solar_midnight = location.solar_midnight(date) if self.data['sunrise_offset'] is not None: sunrise = sunrise + self.data['sunrise_offset'] if self.data['sunset_offset'] is not None: sunset = sunset + self.data['sunset_offset'] return { SUN_EVENT_SUNRISE: sunrise, SUN_EVENT_SUNSET: sunset, 'solar_noon': solar_noon, 'solar_midnight': solar_midnight }
def calc_percent(self): utcnow = dt_utcnow() now = as_local(utcnow) today_sun_times = self.get_sunrise_sunset(now) now_seconds = now.timestamp() today_sunrise_seconds = today_sun_times[SUN_EVENT_SUNRISE].timestamp() today_sunset_seconds = today_sun_times[SUN_EVENT_SUNSET].timestamp() 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 if today_sun_times['solar_midnight'] > yesterday_sun_times[ SUN_EVENT_SUNSET] and today_sun_times[ 'solar_midnight'] < today_sun_times[SUN_EVENT_SUNRISE]: x2 = today_solar_midnight_seconds else: x2 = yesterday_solar_midnight_seconds y2 = -100 x3 = today_sunrise_seconds y3 = 0 elif now > today_sun_times[SUN_EVENT_SUNSET]: tomorrow_sun_times = self.get_sunrise_sunset(now + timedelta(days=1)) tomorrow_sunrise_seconds = tomorrow_sun_times[ SUN_EVENT_SUNRISE].timestamp() tomorrow_sunset_seconds = tomorrow_sun_times[ SUN_EVENT_SUNSET].timestamp() tomorrow_solar_midnight_seconds = tomorrow_sun_times[ 'solar_midnight'].timestamp() x1 = today_sunset_seconds y1 = 0 if today_sun_times['solar_midnight'] > today_sun_times[ SUN_EVENT_SUNSET] and today_sun_times[ 'solar_midnight'] < tomorrow_sun_times[ SUN_EVENT_SUNRISE]: x2 = today_solar_midnight_seconds else: x2 = tomorrow_solar_midnight_seconds y2 = -100 x3 = tomorrow_sunrise_seconds y3 = 0 else: x1 = today_sunrise_seconds y1 = 0 x2 = today_solar_noon_seconds y2 = 100 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 d1 = -y1 + y2 a2 = -x2**2 + x3**2 b2 = -x2 + x3 d2 = -y2 + y3 bm = -(b2 / b1) a3 = bm * a1 + a2 d3 = bm * d1 + d2 a = d3 / a3 b = (d1 - a1 * a) / b1 c = y1 - a * x1**2 - b * x1 percentage = a * now_seconds**2 + b * now_seconds + c _LOGGER.debug("percentage: " + str(percentage)) return percentage
def flux_update(self, utcnow=None): """Update all the lights using flux.""" if utcnow is None: utcnow = dt_utcnow() now = as_local(utcnow) sunset = get_astral_event_date(self.hass, SUN_EVENT_SUNSET, now.date()) start_time = self.find_start_time(now) stop_time = self.find_stop_time(now) if stop_time <= start_time: # stop_time does not happen in the same day as start_time if start_time < now: # stop time is tomorrow stop_time += datetime.timedelta(days=1) elif now < start_time: # stop_time was yesterday since the new start_time is not reached stop_time -= datetime.timedelta(days=1) if start_time < now < sunset: # Daytime time_state = 'day' temp_range = abs(self._start_colortemp - self._sunset_colortemp) day_length = int(sunset.timestamp() - start_time.timestamp()) seconds_from_start = int(now.timestamp() - start_time.timestamp()) percentage_complete = seconds_from_start / day_length temp_offset = temp_range * percentage_complete if self._start_colortemp > self._sunset_colortemp: temp = self._start_colortemp - temp_offset else: temp = self._start_colortemp + temp_offset else: # Night time time_state = 'night' if now < stop_time: if stop_time < start_time and stop_time.day == sunset.day: # we need to use yesterday's sunset time sunset_time = sunset - datetime.timedelta(days=1) else: sunset_time = sunset night_length = int(stop_time.timestamp() - sunset_time.timestamp()) seconds_from_sunset = int(now.timestamp() - sunset_time.timestamp()) percentage_complete = seconds_from_sunset / night_length else: percentage_complete = 1 temp_range = abs(self._sunset_colortemp - self._stop_colortemp) temp_offset = temp_range * percentage_complete if self._sunset_colortemp > self._stop_colortemp: temp = self._sunset_colortemp - temp_offset else: temp = self._sunset_colortemp + temp_offset rgb = color_temperature_to_rgb(temp) x_val, y_val, b_val = color_RGB_to_xy_brightness(*rgb) brightness = self._brightness if self._brightness else b_val if self._disable_brightness_adjust: brightness = None if self._mode == MODE_XY: set_lights_xy(self.hass, self._lights, x_val, y_val, brightness, self._transition) _LOGGER.info("Lights updated to x:%s y:%s brightness:%s, %s%% " "of %s cycle complete at %s", x_val, y_val, brightness, round( percentage_complete * 100), time_state, now) elif self._mode == MODE_RGB: set_lights_rgb(self.hass, self._lights, rgb, self._transition) _LOGGER.info("Lights updated to rgb:%s, %s%% " "of %s cycle complete at %s", rgb, round(percentage_complete * 100), time_state, now) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) set_lights_temp(self.hass, self._lights, mired, brightness, self._transition) _LOGGER.info("Lights updated to mired:%s brightness:%s, %s%% " "of %s cycle complete at %s", mired, brightness, round(percentage_complete * 100), time_state, now)
def get_sunrise_sunset(self, date=None): if (self.data["sunrise_time"] is not None and self.data["sunset_time"] is not None): if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data["sunrise_time"].strftime("%H")), minute=int(self.data["sunrise_time"].strftime("%M")), second=int(self.data["sunrise_time"].strftime("%S")), microsecond=int(self.data["sunrise_time"].strftime("%f")), ) sunset = date.replace( hour=int(self.data["sunset_time"].strftime("%H")), minute=int(self.data["sunset_time"].strftime("%M")), second=int(self.data["sunset_time"].strftime("%S")), microsecond=int(self.data["sunset_time"].strftime("%f")), ) 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() date = as_local(utcdate) sunrise = date.replace( hour=int(self.data["sunrise_time"].strftime("%H")), minute=int(self.data["sunrise_time"].strftime("%M")), second=int(self.data["sunrise_time"].strftime("%S")), microsecond=int(self.data["sunrise_time"].strftime("%f")), ) else: sunrise = location.sunrise(date) if self.data["sunset_time"] is not None: if date is None: utcdate = dt_utcnow() date = as_local(utcdate) sunset = date.replace( hour=int(self.data["sunset_time"].strftime("%H")), minute=int(self.data["sunset_time"].strftime("%M")), second=int(self.data["sunset_time"].strftime("%S")), microsecond=int(self.data["sunset_time"].strftime("%f")), ) else: sunset = location.sunset(date) solar_noon = location.solar_noon(date) solar_midnight = location.solar_midnight(date) if self.data["sunrise_offset"] is not None: sunrise = sunrise + self.data["sunrise_offset"] if self.data["sunset_offset"] is not None: sunset = sunset + self.data["sunset_offset"] return { SUN_EVENT_SUNRISE: sunrise, SUN_EVENT_SUNSET: sunset, "solar_noon": solar_noon, "solar_midnight": solar_midnight, }