async def async_update(self): """Update the state of the sensor.""" import hdate now = dt_util.as_local(dt_util.now()) _LOGGER.debug("Now: %s Timezone = %s", now, now.tzinfo) today = now.date() sunset = dt_util.as_local(get_astral_event_date( self.hass, SUN_EVENT_SUNSET, today)) _LOGGER.debug("Now: %s Sunset: %s", now, sunset) if now > sunset: today += timedelta(1) date = hdate.HDate( today, diaspora=self.diaspora, hebrew=self._hebrew) if self.type == 'date': self._state = date.hebrew_date elif self.type == 'weekly_portion': self._state = date.parasha elif self.type == 'holiday_name': self._state = date.holiday_description elif self.type == 'holyness': self._state = date.holiday_type else: times = hdate.Zmanim( date=today, latitude=self.latitude, longitude=self.longitude, timezone=self.timezone, hebrew=self._hebrew).zmanim self._state = times[self.type].time() _LOGGER.debug("New value: %s", self._state)
def update(self): """ Gets the latest data and updates the states. """ time_date = dt_util.utcnow() time = dt_util.datetime_to_time_str(dt_util.as_local(time_date)) time_utc = dt_util.datetime_to_time_str(time_date) date = dt_util.datetime_to_date_str(dt_util.as_local(time_date)) # Calculate the beat (Swatch Internet Time) time without date. hours, minutes, seconds = time_date.strftime('%H:%M:%S').split(':') beat = ((int(seconds) + (int(minutes) * 60) + ((int(hours) + 1) * 3600)) / 86.4) if self.type == 'time': self._state = time elif self.type == 'date': self._state = date elif self.type == 'date_time': self._state = date + ', ' + time elif self.type == 'time_date': self._state = time + ', ' + date elif self.type == 'time_utc': self._state = time_utc elif self.type == 'beat': self._state = '{0:.2f}'.format(beat)
def update(self): """Get the latest data from opendata.ch.""" response = requests.get( _RESOURCE + 'connections?' + 'from=' + self.start + '&' + 'to=' + self.destination + '&' + 'fields[]=connections/from/departureTimestamp/&' + 'fields[]=connections/', timeout=10) connections = response.json()['connections'][:2] try: self.times = [ dt_util.as_local( dt_util.utc_from_timestamp( item['from']['departureTimestamp'])).strftime( TIME_STR_FORMAT) for item in connections ] self.times.append( dt_util.as_local( dt_util.utc_from_timestamp( connections[0]['from']['departureTimestamp'])) - dt_util.as_local(dt_util.utcnow())) except KeyError: self.times = ['n/a']
def update(self): """ Gets the latest data from opendata.ch. """ response = requests.get( _RESOURCE + "connections?" + "from=" + self.start + "&" + "to=" + self.destination + "&" + "fields[]=connections/from/departureTimestamp/&" + "fields[]=connections/", timeout=30, ) connections = response.json()["connections"][:2] try: self.times = [ dt_util.datetime_to_time_str( dt_util.as_local(dt_util.utc_from_timestamp(item["from"]["departureTimestamp"])) ) for item in connections ] self.times.append( dt_util.as_local(dt_util.utc_from_timestamp(connections[0]["from"]["departureTimestamp"])) - dt_util.as_local(dt_util.utcnow()) ) except KeyError: self.times = ["n/a"]
def flux_update(self, now=None): """Update all the lights using flux.""" if now is None: now = dt_now() sunset = next_setting(self.hass, SUN).replace(day=now.day, month=now.month, year=now.year) start_time = self.find_start_time(now) stop_time = now.replace(hour=self._stop_time.hour, minute=self._stop_time.minute, second=0) 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: # Nightime time_state = 'night' if now < stop_time and now > start_time: now_time = now else: now_time = stop_time temp_range = abs(self._sunset_colortemp - self._stop_colortemp) night_length = int(stop_time.timestamp() - sunset.timestamp()) seconds_from_sunset = int(now_time.timestamp() - sunset.timestamp()) percentage_complete = seconds_from_sunset / night_length 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 x_val, y_val, b_val = color_RGB_to_xy(*color_temperature_to_rgb(temp)) brightness = self._brightness if self._brightness else b_val if self._mode == MODE_XY: set_lights_xy(self.hass, self._lights, x_val, y_val, brightness) _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, as_local(now)) else: # Convert to mired and clamp to allowed values mired = color_temperature_kelvin_to_mired(temp) mired = max(HASS_COLOR_MIN, min(mired, HASS_COLOR_MAX)) set_lights_temp(self.hass, self._lights, mired, brightness) _LOGGER.info("Lights updated to mired:%s brightness:%s, %s%%" " of %s cycle complete at %s", mired, brightness, round(percentage_complete * 100), time_state, as_local(now))
def update(self): """Get the latest data and updates the states.""" time_date = dt_util.utcnow() time = dt_util.as_local(time_date).strftime(TIME_STR_FORMAT) time_utc = time_date.strftime(TIME_STR_FORMAT) date = dt_util.as_local(time_date).date().isoformat() # Calculate Swatch Internet Time. time_bmt = time_date + timedelta(hours=1) delta = timedelta(hours=time_bmt.hour, minutes=time_bmt.minute, seconds=time_bmt.second, microseconds=time_bmt.microsecond) beat = int((delta.seconds + delta.microseconds / 1000000.0) / 86.4) if self.type == 'time': self._state = time elif self.type == 'date': self._state = date elif self.type == 'date_time': self._state = date + ', ' + time elif self.type == 'time_date': self._state = time + ', ' + date elif self.type == 'time_utc': self._state = time_utc elif self.type == 'beat': self._state = '@{0:03d}'.format(beat)
def flux_update(self, now=dt_now()): """Update all the lights using flux.""" sunset = next_setting(self.hass, SUN).replace(day=now.day, month=now.month, year=now.year) start_time = self.find_start_time(now) stop_time = now.replace(hour=self._stop_time.hour, minute=self._stop_time.minute, second=0) 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: # Nightime time_state = 'night' if now < stop_time and now > start_time: now_time = now else: now_time = stop_time temp_range = abs(self._sunset_colortemp - self._stop_colortemp) night_length = int(stop_time.timestamp() - sunset.timestamp()) seconds_from_sunset = int(now_time.timestamp() - sunset.timestamp()) percentage_complete = seconds_from_sunset / night_length 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 if self._mode == MODE_XY: x_val, y_val, b_val = color_RGB_to_xy(*temp_to_rgb(temp)) brightness = self._brightness if self._brightness else b_val set_lights_xy(self.hass, self._lights, x_val, y_val, brightness) _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, as_local(now)) else: set_lights_temp(self.hass, self._lights, temp, self._mode) _LOGGER.info("Lights updated to temp:%s, %s%%" " of %s cycle complete at %s", temp, round(percentage_complete * 100), time_state, as_local(now))
def update_period(self): """Parse the templates and store a datetime tuple in _period.""" start = None end = None # Parse start if self._start is not None: try: start_rendered = self._start.render() except (TemplateError, TypeError) as ex: HistoryStatsHelper.handle_template_exception(ex, 'start') return start = dt_util.parse_datetime(start_rendered) if start is None: try: start = dt_util.as_local(dt_util.utc_from_timestamp( math.floor(float(start_rendered)))) except ValueError: _LOGGER.error("Parsing error: start must be a datetime" "or a timestamp") return # Parse end if self._end is not None: try: end_rendered = self._end.render() except (TemplateError, TypeError) as ex: HistoryStatsHelper.handle_template_exception(ex, 'end') return end = dt_util.parse_datetime(end_rendered) if end is None: try: end = dt_util.as_local(dt_util.utc_from_timestamp( math.floor(float(end_rendered)))) except ValueError: _LOGGER.error("Parsing error: end must be a datetime " "or a timestamp") return # Calculate start or end using the duration if start is None: start = end - self._duration if end is None: end = start + self._duration if start > dt_util.now(): # History hasn't been written yet for this period return if dt_util.now() < end: # No point in making stats of the future end = dt_util.now() self._period = start, end
def _purge_old(self): """Remove states which are older than self._max_age.""" now = dt_util.utcnow() _LOGGER.debug("%s: purging records older then %s(%s)", self.entity_id, dt_util.as_local(now - self._max_age), self._max_age) while self.ages and (now - self.ages[0]) > self._max_age: _LOGGER.debug("%s: purging record with datetime %s(%s)", self.entity_id, dt_util.as_local(self.ages[0]), (now - self.ages[0])) self.ages.popleft() self.states.popleft()
async def async_update(self): """Update the state.""" data = self.openuv.data[DATA_PROTECTION_WINDOW]['result'] if self._sensor_type == TYPE_PROTECTION_WINDOW: self._state = parse_datetime( data['from_time']) <= utcnow() <= parse_datetime( data['to_time']) self._attrs.update({ ATTR_PROTECTION_WINDOW_ENDING_TIME: as_local(parse_datetime(data['to_time'])), ATTR_PROTECTION_WINDOW_ENDING_UV: data['to_uv'], ATTR_PROTECTION_WINDOW_STARTING_UV: data['from_uv'], ATTR_PROTECTION_WINDOW_STARTING_TIME: as_local(parse_datetime(data['from_time'])), })
def device_state_attributes(self): """Return the state attributes of the DWD-Weather-Warnings.""" data = { ATTR_ATTRIBUTION: ATTRIBUTION, 'region_name': self._api.region_name } if self._api.region_id is not None: data['region_id'] = self._api.region_id if self._api.region_state is not None: data['region_state'] = self._api.region_state if self._api.data['time'] is not None: data['last_update'] = dt_util.as_local( dt_util.utc_from_timestamp(self._api.data['time'] / 1000)) if self._var_id == 'current_warning_level': prefix = 'current' elif self._var_id == 'advance_warning_level': prefix = 'advance' else: raise Exception('Unknown warning type') data['warning_count'] = self._api.data[prefix + '_warning_count'] i = 0 for event in self._api.data[prefix + '_warnings']: i = i + 1 data['warning_{}_name'.format(i)] = event['event'] data['warning_{}_level'.format(i)] = event['level'] data['warning_{}_type'.format(i)] = event['type'] if event['headline']: data['warning_{}_headline'.format(i)] = event['headline'] if event['description']: data['warning_{}_description'.format(i)] = event['description'] if event['instruction']: data['warning_{}_instruction'.format(i)] = event['instruction'] if event['start'] is not None: data['warning_{}_start'.format(i)] = dt_util.as_local( dt_util.utc_from_timestamp(event['start'] / 1000)) if event['end'] is not None: data['warning_{}_end'.format(i)] = dt_util.as_local( dt_util.utc_from_timestamp(event['end'] / 1000)) return data
def media_start_time(self): """Start time the program aired.""" if self._is_standby: return None return dt_util.as_local( dt_util.utc_from_timestamp(self._current['startTime']))
def render(hass, template, variables=None, **kwargs): """Render given template.""" if variables is not None: kwargs.update(variables) location_methods = LocationMethods(hass) utcnow = dt_util.utcnow() try: return ( ENV.from_string( template, { "closest": location_methods.closest, "distance": location_methods.distance, "float": forgiving_float, "is_state": hass.states.is_state, "is_state_attr": hass.states.is_state_attr, "now": dt_util.as_local(utcnow), "states": AllStates(hass), "utcnow": utcnow, "as_timestamp": dt_util.as_timestamp, "relative_time": dt_util.get_age, }, ) .render(kwargs) .strip() ) except jinja2.TemplateError as err: raise TemplateError(err)
def timestamp_local(value): """Filter to convert given timestamp to local date/time.""" try: return dt_util.as_local(dt_util.utc_from_timestamp(value)).strftime(DATE_STR_FORMAT) except (ValueError, TypeError): # If timestamp can't be converted return value
def _update_current_price(self): state = None max_price = 0 min_price = 10000 sum_price = 0 num = 0 now = dt_util.now() for key, price_total in self._tibber_home.price_total.items(): price_time = dt_util.as_local(dt_util.parse_datetime(key)) price_total = round(price_total, 3) time_diff = (now - price_time).total_seconds()/60 if (not self._last_data_timestamp or price_time > self._last_data_timestamp): self._last_data_timestamp = price_time if 0 <= time_diff < 60: state = price_total self._last_updated = price_time if now.date() == price_time.date(): max_price = max(max_price, price_total) min_price = min(min_price, price_total) num += 1 sum_price += price_total self._state = state self._device_state_attributes['max_price'] = max_price self._device_state_attributes['avg_price'] = round(sum_price / num, 3) self._device_state_attributes['min_price'] = min_price return state is not None
async def async_update(self): """Update the state.""" data = self.openuv.data[DATA_UV]['result'] if self._sensor_type == TYPE_CURRENT_OZONE_LEVEL: self._state = data['ozone'] elif self._sensor_type == TYPE_CURRENT_UV_INDEX: self._state = data['uv'] elif self._sensor_type == TYPE_CURRENT_UV_LEVEL: if data['uv'] >= 11: self._state = UV_LEVEL_EXTREME elif data['uv'] >= 8: self._state = UV_LEVEL_VHIGH elif data['uv'] >= 6: self._state = UV_LEVEL_HIGH elif data['uv'] >= 3: self._state = UV_LEVEL_MODERATE else: self._state = UV_LEVEL_LOW elif self._sensor_type == TYPE_MAX_UV_INDEX: self._state = data['uv_max'] self._attrs.update({ ATTR_MAX_UV_TIME: as_local(parse_datetime(data['uv_max_time'])) }) elif self._sensor_type in (TYPE_SAFE_EXPOSURE_TIME_1, TYPE_SAFE_EXPOSURE_TIME_2, TYPE_SAFE_EXPOSURE_TIME_3, TYPE_SAFE_EXPOSURE_TIME_4, TYPE_SAFE_EXPOSURE_TIME_5, TYPE_SAFE_EXPOSURE_TIME_6): self._state = data['safe_exposure_time'][EXPOSURE_TYPE_MAP[ self._sensor_type]]
def _get_date(date): """Get the dateTime from date or dateTime as a local.""" if 'date' in date: return dt.start_of_local_day(dt.dt.datetime.combine( dt.parse_date(date['date']), dt.dt.time.min)) else: return dt.as_local(dt.parse_datetime(date['dateTime']))
def sun(hass, before=None, after=None, before_offset=None, after_offset=None): """Test if current time matches sun requirements.""" utcnow = dt_util.utcnow() today = dt_util.as_local(utcnow).date() before_offset = before_offset or timedelta(0) after_offset = after_offset or timedelta(0) sunrise = get_astral_event_date(hass, 'sunrise', today) sunset = get_astral_event_date(hass, 'sunset', today) if sunrise is None and SUN_EVENT_SUNRISE in (before, after): # There is no sunrise today return False if sunset is None and SUN_EVENT_SUNSET in (before, after): # There is no sunset today return False if before == SUN_EVENT_SUNRISE and utcnow > sunrise + before_offset: return False if before == SUN_EVENT_SUNSET and utcnow > sunset + before_offset: return False if after == SUN_EVENT_SUNRISE and utcnow < sunrise + after_offset: return False if after == SUN_EVENT_SUNSET and utcnow < sunset + after_offset: return False return True
def __repr__(self): """Return the representation of the states.""" attr = "; {}".format(util.repr_helper(self.attributes)) if self.attributes else "" return "<state {}={}{} @ {}>".format( self.entity_id, self.state, attr, dt_util.as_local(self.last_changed).isoformat() )
def get_astral_event_next( hass: HomeAssistantType, event: str, utc_point_in_time: Optional[datetime.datetime] = None, offset: Optional[datetime.timedelta] = None) -> datetime.datetime: """Calculate the next specified solar event.""" from astral import AstralError location = get_astral_location(hass) if offset is None: offset = datetime.timedelta() if utc_point_in_time is None: utc_point_in_time = dt_util.utcnow() mod = -1 while True: try: next_dt = getattr(location, event)( dt_util.as_local(utc_point_in_time).date() + datetime.timedelta(days=mod), local=False) + offset # type: datetime.datetime if next_dt > utc_point_in_time: return next_dt except AstralError: pass mod += 1
def forecast(self) -> List: """Return the forecast.""" if self._forecasts is None: return None data = [] for forecast in self._forecasts: condition = next(( k for k, v in CONDITION_CLASSES.items() if forecast.symbol in v), None) # Only get mid day forecasts if forecast.valid_time.hour == 12: data.append({ ATTR_FORECAST_TIME: dt.as_local(forecast.valid_time), ATTR_FORECAST_TEMP: forecast.temperature_max, ATTR_FORECAST_TEMP_LOW: forecast.temperature_min, ATTR_FORECAST_PRECIPITATION: round(forecast.mean_precipitation*24), ATTR_FORECAST_CONDITION: condition }) return data
def next_midnight(hass, entity_id=None): """Local datetime object of the next midnight. Async friendly. """ utc_next = next_midnight_utc(hass, entity_id) return dt_util.as_local(utc_next) if utc_next else None
def next_rising(hass, entity_id=None): """Local datetime object of the next sun rising. Async friendly. """ utc_next = next_rising_utc(hass, entity_id) return dt_util.as_local(utc_next) if utc_next else None
def next_noon(hass, entity_id=None): """Local datetime object of the next solar noon. Async friendly. """ utc_next = next_noon_utc(hass, entity_id) return dt_util.as_local(utc_next) if utc_next else None
def test_as_local_with_utc_object(self): dt_util.set_default_time_zone(dt_util.get_time_zone(TEST_TIME_ZONE)) utcnow = dt_util.utcnow() localnow = dt_util.as_local(utcnow) self.assertEqual(localnow, utcnow) self.assertNotEqual(localnow.tzinfo, utcnow.tzinfo)
def update_period(self): """Parse the templates and store a datetime tuple in _period.""" start = None end = None # Parse start if self._start is not None: try: start_rendered = self._start.render() except (TemplateError, TypeError) as ex: HistoryStatsHelper.handle_template_exception(ex, 'start') return start = dt_util.parse_datetime(start_rendered) if start is None: try: start = dt_util.as_local(dt_util.utc_from_timestamp( math.floor(float(start_rendered)))) except ValueError: _LOGGER.error('PARSING ERROR: start must be a datetime' ' or a timestamp.') return # Parse end if self._end is not None: try: end_rendered = self._end.render() except (TemplateError, TypeError) as ex: HistoryStatsHelper.handle_template_exception(ex, 'end') return end = dt_util.parse_datetime(end_rendered) if end is None: try: end = dt_util.as_local(dt_util.utc_from_timestamp( math.floor(float(end_rendered)))) except ValueError: _LOGGER.error('PARSING ERROR: end must be a datetime' ' or a timestamp.') return # Calculate start or end using the duration if start is None: start = end - self._duration if end is None: end = start + self._duration self._period = start, end
def update(self): """Get the latest system information.""" import psutil if self.type == 'disk_use_percent': self._state = psutil.disk_usage(self.argument).percent elif self.type == 'disk_use': self._state = round(psutil.disk_usage(self.argument).used / 1024**3, 1) elif self.type == 'disk_free': self._state = round(psutil.disk_usage(self.argument).free / 1024**3, 1) elif self.type == 'memory_use_percent': self._state = psutil.virtual_memory().percent elif self.type == 'memory_use': self._state = round((psutil.virtual_memory().total - psutil.virtual_memory().available) / 1024**2, 1) elif self.type == 'memory_free': self._state = round(psutil.virtual_memory().available / 1024**2, 1) elif self.type == 'swap_use_percent': self._state = psutil.swap_memory().percent elif self.type == 'swap_use': self._state = round(psutil.swap_memory().used / 1024**3, 1) elif self.type == 'swap_free': self._state = round(psutil.swap_memory().free / 1024**3, 1) elif self.type == 'processor_use': self._state = round(psutil.cpu_percent(interval=None)) elif self.type == 'process': if any(self.argument in l.name() for l in psutil.process_iter()): self._state = STATE_ON else: self._state = STATE_OFF elif self.type == 'network_out' or self.type == 'network_in': counters = psutil.net_io_counters(pernic=True) if self.argument in counters: counter = counters[self.argument][IO_COUNTER[self.type]] self._state = round(counter / 1024**2, 1) else: self._state = STATE_UNKNOWN elif self.type == 'packets_out' or self.type == 'packets_in': counters = psutil.net_io_counters(pernic=True) if self.argument in counters: self._state = counters[self.argument][IO_COUNTER[self.type]] else: self._state = STATE_UNKNOWN elif self.type == 'ipv4_address' or self.type == 'ipv6_address': addresses = psutil.net_if_addrs() if self.argument in addresses: self._state = addresses[self.argument][IF_ADDRS[self.type]][1] else: self._state = STATE_UNKNOWN elif self.type == 'last_boot': self._state = dt_util.as_local( dt_util.utc_from_timestamp(psutil.boot_time()) ).date().isoformat() elif self.type == 'since_last_boot': self._state = dt_util.utcnow() - dt_util.utc_from_timestamp( psutil.boot_time())
def test_as_local_with_utc_object(self): """Test local time with UTC object.""" dt_util.set_default_time_zone(dt_util.get_time_zone(TEST_TIME_ZONE)) utcnow = dt_util.utcnow() localnow = dt_util.as_local(utcnow) assert localnow == utcnow assert localnow.tzinfo != utcnow.tzinfo
def busy_callback(worker_count, current_jobs, pending_jobs_count): """Callback to be called when the pool queue gets too big.""" _LOGGER.warning( "WorkerPool:All %d threads are busy and %d jobs pending", worker_count, pending_jobs_count) for start, job in current_jobs: _LOGGER.warning("WorkerPool:Current job from %s: %s", dt_util.as_local(start).isoformat(), job)
def timestamp_custom(value, date_format=DATE_STR_FORMAT, local=True): """Filter to convert given timestamp to format.""" try: date = dt_util.utc_from_timestamp(value) if local: date = dt_util.as_local(date) return date.strftime(date_format) except (ValueError, TypeError): # If timestamp can't be converted return value
def convert_until(status_dict, until_key) -> str: """Convert datetime string from "%Y-%m-%dT%H:%M:%SZ" to local/aware/isoformat.""" if until_key in status_dict: # only present for certain modes dt_utc_naive = dt_util.parse_datetime(status_dict[until_key]) status_dict[until_key] = dt_util.as_local(dt_utc_naive).isoformat()
def test_sun_offset(self): """Test sun event with offset.""" test_time = self.hass.config.time_zone.localize(datetime( 2019, 1, 12)).astimezone(pytz.UTC) sunrise = dt_util.as_local( get_astral_event_date(self.hass, 'sunrise', dt_util.as_utc(test_time)) + timedelta(hours=-1, minutes=-30)) sunset = dt_util.as_local( get_astral_event_date(self.hass, 'sunset', dt_util.as_utc( test_time)) + timedelta(hours=1, minutes=30)) config = { 'binary_sensor': [{ 'platform': 'tod', 'name': 'Day', 'after': 'sunrise', 'after_offset': '-1:30', 'before': 'sunset', 'before_offset': '1:30' }] } entity_id = 'binary_sensor.day' testtime = sunrise + timedelta(seconds=-1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): setup_component(self.hass, 'binary_sensor', config) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunrise with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise + timedelta(seconds=1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON self.hass.block_till_done() testtime = sunset + timedelta(seconds=-1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON self.hass.block_till_done() testtime = sunset with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF self.hass.block_till_done() testtime = sunset + timedelta(seconds=1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF test_time = test_time + timedelta(days=1) sunrise = dt_util.as_local( get_astral_event_date(self.hass, 'sunrise', dt_util.as_utc(test_time)) + timedelta(hours=-1, minutes=-30)) testtime = sunrise with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON
def device_state_attributes(self): """Return the attributes.""" coordinator_data = self.coordinator.data starman_data = coordinator_data["starman"] launch_data = coordinator_data["next_launch"] latest_launch_data = coordinator_data["latest_launch"] if self._kind == "spacex_next_launch_mission": self.attrs["mission_patch"] = launch_data["links"].get( "patch", {}).get("large") if launch_data.get("details"): self.attrs["details"] = launch_data["details"][0:255] if len(launch_data["details"]) > 255: self.attrs["details2"] = launch_data["details"][255:510] else: self.attrs["details2"] = "" if len(launch_data["details"]) > 510: self.attrs["details3"] = launch_data["details"][510:765] else: self.attrs["details3"] = "" self.attrs["video_link"] = launch_data["links"].get("webcast") elif self._kind == "spacex_next_launch_day": self.attrs["launch_date_unix"] = launch_data["date_unix"] self.attrs["launch_date_utc"] = launch_data["date_utc"] elif self._kind == "spacex_next_launch_time": self.attrs["launch_time_24h"] = self._state = as_local( utc_from_timestamp(launch_data["date_unix"])).strftime("%H:%M") elif self._kind == "spacex_next_launch_countdown": if launch_data["tbd"]: self.attrs["t0_countdown"] = "NA" else: t0_countdown = int(launch_data["date_unix"]) - int(time.time()) day = t0_countdown // (24 * 3600) t0_countdown = t0_countdown % (24 * 3600) hour = t0_countdown // 3600 t0_countdown %= 3600 minutes = t0_countdown // 60 t0_countdown %= 60 seconds = t0_countdown countdown_string = "" if day > 0: countdown_string = f"{day} days, " if hour > 0: countdown_string = f"{countdown_string}{hour} hours, " if minutes > 0: countdown_string = f"{countdown_string}{minutes} minutes, " countdown_string = f"{countdown_string}{seconds} seconds until the launch of {launch_data['name']}." self.attrs["t0_countdown"] = countdown_string elif self._kind == "spacex_next_confirmed_launch_day": if launch_data["tbd"]: self.attrs["launch_date_unix"] = "NA" self.attrs["launch_date_utc"] = "NA" else: self.attrs["launch_date_unix"] = launch_data["date_unix"] self.attrs["launch_date_utc"] = launch_data["date_utc"] elif self._kind == "spacex_next_confirmed_launch_time": self.attrs["launch_time_24h"] = self._state = as_local( utc_from_timestamp(launch_data["date_unix"])).strftime("%H:%M") elif self._kind == "spacex_next_launch_site": self.attrs["short_name"] = launch_data["launch_site"]["name"] elif self._kind == "spacex_next_launch_rocket": core_counter = 1 for this_core in launch_data["cores_detail"]: self.attrs["core_" + str(core_counter) + "_serial"] = this_core.get("details", {}).get("serial") self.attrs["core_" + str(core_counter) + "_flight"] = this_core.get("flight") self.attrs["core_" + str(core_counter) + "_block"] = this_core.get("details", {}).get("block") self.attrs["core_" + str(core_counter) + "_landing_intent"] = this_core.get( "landing_attempt") if this_core.get("landpad"): self.attrs["core_" + str(core_counter) + "_lz"] = this_core["landpad"]["name"] self.attrs["core_" + str(core_counter) + "_lz_long"] = this_core["landpad"]["full_name"] else: self.attrs["core_" + str(core_counter) + "_lz"] = "NA" self.attrs["core_" + str(core_counter) + "_lz_long"] = "NA" core_counter = core_counter + 1 if launch_data.get("fairings"): self.attrs["fairings_reused"] = launch_data.get( "fairings", {}).get("reused") else: self.attrs["fairings_reused"] = "NA" elif self._kind == "spacex_next_launch_payload": if len(launch_data["payloads_detail"]): if len(launch_data["payloads_detail"][0]["nationalities"]): self.attrs["nationality"] = launch_data["payloads_detail"][ 0]["nationalities"][0] else: self.attrs["nationality"] = "NA" if len(launch_data["payloads_detail"][0]["manufacturers"]): self.attrs["manufacturer"] = launch_data[ "payloads_detail"][0]["manufacturers"][0] else: self.attrs["manufacturer"] = "NA" self.attrs["payload_type"] = launch_data["payloads_detail"][0][ "type"] self.attrs["payload_mass"] = ( str(launch_data["payloads_detail"][0]["mass_kg"]) + " kg") self.attrs["payload_mass_us"] = ( str(launch_data["payloads_detail"][0]["mass_lbs"]) + " lbs") self.attrs["orbit"] = launch_data["payloads_detail"][0]["orbit"] elif self._kind == "spacex_latest_launch_mission": self.attrs["mission_patch"] = latest_launch_data["links"].get( "patch", {}).get("large") if latest_launch_data.get("details"): self.attrs["details"] = latest_launch_data["details"][0:255] if len(latest_launch_data["details"]) > 255: self.attrs["details2"] = latest_launch_data["details"][ 255:510] else: self.attrs["details2"] = "" if len(latest_launch_data["details"]) > 510: self.attrs["details3"] = latest_launch_data["details"][ 510:765] else: self.attrs["details3"] = "" self.attrs["video_link"] = latest_launch_data["links"].get( "webcast") elif self._kind == "spacex_latest_launch_day": self.attrs["launch_date_unix"] = latest_launch_data["date_unix"] self.attrs["launch_date_utc"] = latest_launch_data["date_utc"] elif self._kind == "spacex_latest_launch_time": self.attrs["launch_time_24h"] = self._state = as_local( utc_from_timestamp( latest_launch_data["date_unix"])).strftime("%H:%M") elif self._kind == "spacex_latest_launch_site": self.attrs["short_name"] = latest_launch_data["launch_site"][ "name"] elif self._kind == "spacex_latest_launch_rocket": core_counter = 1 for this_core in latest_launch_data["cores_detail"]: self.attrs["core_" + str(core_counter) + "_serial"] = this_core["details"]["serial"] self.attrs["core_" + str(core_counter) + "_flight"] = this_core["flight"] self.attrs["core_" + str(core_counter) + "_block"] = this_core["details"]["block"] self.attrs["core_" + str(core_counter) + "_landing_intent"] = this_core["landing_attempt"] self.attrs["core_" + str(core_counter) + "_lz"] = this_core["landpad"]["name"] self.attrs["core_" + str(core_counter) + "_lz_long"] = this_core["landpad"]["full_name"] core_counter = core_counter + 1 if latest_launch_data.get("fairings"): self.attrs["fairings_reused"] = latest_launch_data[ "fairings"].get("reused") elif self._kind == "spacex_latest_launch_payload": if len(latest_launch_data["payloads_detail"]): if len(latest_launch_data["payloads_detail"][0] ["nationalities"]): self.attrs["nationality"] = latest_launch_data[ "payloads_detail"][0]["nationalities"][0] else: self.attrs["nationality"] = "NA" if len(latest_launch_data["payloads_detail"][0] ["manufacturers"]): self.attrs["manufacturer"] = latest_launch_data[ "payloads_detail"][0]["manufacturers"][0] else: self.attrs["manufacturer"] = "NA" self.attrs["payload_type"] = latest_launch_data[ "payloads_detail"][0]["type"] self.attrs["payload_mass"] = ( str(latest_launch_data["payloads_detail"][0]["mass_kg"]) + " kg") self.attrs["payload_mass_us"] = ( str(latest_launch_data["payloads_detail"][0]["mass_lbs"]) + " lbs") self.attrs["orbit"] = latest_launch_data["payloads_detail"][0][ "orbit"] elif self._kind == "spacex_starman_speed": self.attrs["machspeed"] = float(starman_data["speed_kph"]) / 1235 elif self._kind == "spacex_starman_distance": self.attrs["au_distance"] = float( starman_data["earth_distance_km"]) / (1.496 * (10**8)) return self.attrs
async def test_norwegian_case_summer(hass): """Test location in Norway where the sun doesn't set in summer.""" hass.config.latitude = 69.6 hass.config.longitude = 18.8 hass.config.elevation = 10.0 test_time = datetime(2010, 6, 1, tzinfo=dt_util.UTC) sunrise = dt_util.as_local( get_astral_event_next(hass, "sunrise", dt_util.as_utc(test_time))) sunset = dt_util.as_local( get_astral_event_next(hass, "sunset", dt_util.as_utc(sunrise))) config = { "binary_sensor": [{ "platform": "tod", "name": "Day", "after": "sunrise", "before": "sunset", }] } entity_id = "binary_sensor.day" testtime = test_time with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): await async_setup_component(hass, "binary_sensor", config) await hass.async_block_till_done() await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunrise + timedelta(seconds=-1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunrise with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise + timedelta(seconds=1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON await hass.async_block_till_done() testtime = sunset + timedelta(seconds=-1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON await hass.async_block_till_done() testtime = sunset with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF await hass.async_block_till_done() testtime = sunset + timedelta(seconds=1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF
def async_update(self): """Get the time and updates the states.""" from astral import Astral today = dt_util.as_local(dt_util.utcnow()).date() self._state = Astral().moon_phase(today)
def midnight(utc: datetime) -> datetime: """Accept a UTC time and return midnight for that day""" return dt.as_utc( dt.as_local(utc).replace(hour=0, minute=0, second=0, microsecond=0))
def _dt_attr_from_utc(self, utc, tzone): if self._time_as in [TZ_DEVICE_UTC, TZ_DEVICE_LOCAL] and tzone: return utc.astimezone(tzone) if self._time_as in [TZ_LOCAL, TZ_DEVICE_LOCAL]: return dt_util.as_local(utc) return utc
def _local_datetime(hours, minutes): """Build a datetime object for testing in the correct timezone.""" return dt.as_local(datetime.datetime(2017, 11, 27, hours, minutes, 0))
def _process_state(self, value): return (dt.as_local(super()._round_time( datetime.datetime.fromtimestamp(value[self._sensor_property] / 1000, tz=LOCAL_TIMEZONE))).isoformat() if value else STATE_UNAVAILABLE)
def _process_state(self, value): return (dt.as_local(super()._round_time( datetime.datetime.fromtimestamp(self._timestamp.timestamp() + value[self._sensor_property] / 1000))).isoformat() if value and self._timestamp else STATE_UNAVAILABLE)
def sun( hass: HomeAssistant, before: str | None = None, after: str | None = None, before_offset: timedelta | None = None, after_offset: timedelta | None = None, ) -> bool: """Test if current time matches sun requirements.""" utcnow = dt_util.utcnow() today = dt_util.as_local(utcnow).date() before_offset = before_offset or timedelta(0) after_offset = after_offset or timedelta(0) sunrise_today = get_astral_event_date(hass, SUN_EVENT_SUNRISE, today) sunset_today = get_astral_event_date(hass, SUN_EVENT_SUNSET, today) sunrise = sunrise_today sunset = sunset_today if today > dt_util.as_local(cast( datetime, sunrise_today)).date() and SUN_EVENT_SUNRISE in (before, after): tomorrow = dt_util.as_local(utcnow + timedelta(days=1)).date() sunrise_tomorrow = get_astral_event_date(hass, SUN_EVENT_SUNRISE, tomorrow) sunrise = sunrise_tomorrow if today > dt_util.as_local(cast( datetime, sunset_today)).date() and SUN_EVENT_SUNSET in (before, after): tomorrow = dt_util.as_local(utcnow + timedelta(days=1)).date() sunset_tomorrow = get_astral_event_date(hass, SUN_EVENT_SUNSET, tomorrow) sunset = sunset_tomorrow if sunrise is None and SUN_EVENT_SUNRISE in (before, after): # There is no sunrise today condition_trace_set_result(False, message="no sunrise today") return False if sunset is None and SUN_EVENT_SUNSET in (before, after): # There is no sunset today condition_trace_set_result(False, message="no sunset today") return False if before == SUN_EVENT_SUNRISE: wanted_time_before = cast(datetime, sunrise) + before_offset condition_trace_update_result(wanted_time_before=wanted_time_before) if utcnow > wanted_time_before: return False if before == SUN_EVENT_SUNSET: wanted_time_before = cast(datetime, sunset) + before_offset condition_trace_update_result(wanted_time_before=wanted_time_before) if utcnow > wanted_time_before: return False if after == SUN_EVENT_SUNRISE: wanted_time_after = cast(datetime, sunrise) + after_offset condition_trace_update_result(wanted_time_after=wanted_time_after) if utcnow < wanted_time_after: return False if after == SUN_EVENT_SUNSET: wanted_time_after = cast(datetime, sunset) + after_offset condition_trace_update_result(wanted_time_after=wanted_time_after) if utcnow < wanted_time_after: return False return True
def _get_datetime_local( dt_or_d: datetime.datetime | datetime.date, ) -> datetime.datetime: """Convert a calendar event date/datetime to a datetime if needed.""" if isinstance(dt_or_d, datetime.datetime): return dt.as_local(dt_or_d) return dt.start_of_local_day(dt_or_d)
async def test_from_sunset_to_sunrise(hass): """Test period from sunset to sunrise.""" test_time = datetime(2019, 1, 12, tzinfo=dt_util.UTC) sunset = dt_util.as_local(get_astral_event_date(hass, "sunset", test_time)) sunrise = dt_util.as_local(get_astral_event_next(hass, "sunrise", sunset)) # assert sunset == sunrise config = { "binary_sensor": [{ "platform": "tod", "name": "Night", "after": "sunset", "before": "sunrise", }] } entity_id = "binary_sensor.night" testtime = sunset + timedelta(minutes=-1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): await async_setup_component(hass, "binary_sensor", config) await hass.async_block_till_done() await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunset with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunset + timedelta(minutes=1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise + timedelta(minutes=-1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) await hass.async_block_till_done() # assert state == "dupa" assert state.state == STATE_OFF testtime = sunrise + timedelta(minutes=1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF
def _get_api_date( dt_or_d: datetime.datetime | datetime.date) -> dict[str, str]: """Convert a calendar event date/datetime to a datetime if needed.""" if isinstance(dt_or_d, datetime.datetime): return {"dateTime": dt.as_local(dt_or_d).isoformat()} return {"date": dt_or_d.isoformat()}
async def test_sun_offset(hass): """Test sun event with offset.""" test_time = datetime(2019, 1, 12, tzinfo=dt_util.UTC) sunrise = dt_util.as_local( get_astral_event_date(hass, "sunrise", dt_util.as_utc(test_time)) + timedelta(hours=-1, minutes=-30)) sunset = dt_util.as_local( get_astral_event_date(hass, "sunset", dt_util.as_utc(test_time)) + timedelta(hours=1, minutes=30)) config = { "binary_sensor": [{ "platform": "tod", "name": "Day", "after": "sunrise", "after_offset": "-1:30", "before": "sunset", "before_offset": "1:30", }] } entity_id = "binary_sensor.day" testtime = sunrise + timedelta(seconds=-1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): await async_setup_component(hass, "binary_sensor", config) await hass.async_block_till_done() await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunrise with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise + timedelta(seconds=1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON await hass.async_block_till_done() testtime = sunset + timedelta(seconds=-1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON await hass.async_block_till_done() testtime = sunset with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF await hass.async_block_till_done() testtime = sunset + timedelta(seconds=1) with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF test_time = test_time + timedelta(days=1) sunrise = dt_util.as_local( get_astral_event_date(hass, "sunrise", dt_util.as_utc(test_time)) + timedelta(hours=-1, minutes=-30)) testtime = sunrise with patch( "homeassistant.components.tod.binary_sensor.dt_util.utcnow", return_value=testtime, ): hass.bus.async_fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON
def test_as_local_with_naive_object(self): """Test local time with native object.""" now = dt_util.now() self.assertAlmostEqual(now, dt_util.as_local(datetime.utcnow()), delta=timedelta(seconds=1))
async def test_timestamp(hass): """Test timestamp.""" try: dt_util.set_default_time_zone( dt_util.get_time_zone("America/Los_Angeles")) assert await async_setup_component( hass, DOMAIN, { DOMAIN: { "test_datetime_initial_with_tz": { "has_time": True, "has_date": True, "initial": "2020-12-13 10:00:00+01:00", }, "test_datetime_initial_without_tz": { "has_time": True, "has_date": True, "initial": "2020-12-13 10:00:00", }, "test_time_initial": { "has_time": True, "has_date": False, "initial": "10:00:00", }, } }, ) # initial has been converted to the set timezone state_with_tz = hass.states.get( "input_datetime.test_datetime_initial_with_tz") assert state_with_tz is not None # Timezone LA is UTC-8 => timestamp carries +01:00 => delta is -9 => 10:00 - 09:00 => 01:00 assert state_with_tz.state == "2020-12-13 01:00:00" assert (dt_util.as_local( dt_util.utc_from_timestamp( state_with_tz.attributes[ATTR_TIMESTAMP])).strftime( FMT_DATETIME) == "2020-12-13 01:00:00") # initial has been interpreted as being part of set timezone state_without_tz = hass.states.get( "input_datetime.test_datetime_initial_without_tz") assert state_without_tz is not None assert state_without_tz.state == "2020-12-13 10:00:00" # Timezone LA is UTC-8 => timestamp has no zone (= assumed local) => delta to UTC is +8 => 10:00 + 08:00 => 18:00 assert (dt_util.utc_from_timestamp( state_without_tz.attributes[ATTR_TIMESTAMP]).strftime(FMT_DATETIME) == "2020-12-13 18:00:00") assert (dt_util.as_local( dt_util.utc_from_timestamp( state_without_tz.attributes[ATTR_TIMESTAMP])).strftime( FMT_DATETIME) == "2020-12-13 10:00:00") # Use datetime.datetime.fromtimestamp assert (dt_util.as_local( datetime.datetime.fromtimestamp( state_without_tz.attributes[ATTR_TIMESTAMP], datetime.timezone.utc)).strftime(FMT_DATETIME) == "2020-12-13 10:00:00") # Test initial time sets timestamp correctly. state_time = hass.states.get("input_datetime.test_time_initial") assert state_time is not None assert state_time.state == "10:00:00" assert state_time.attributes[ATTR_TIMESTAMP] == 10 * 60 * 60 # Test that setting the timestamp of an entity works. await hass.services.async_call( DOMAIN, "set_datetime", { ATTR_ENTITY_ID: "input_datetime.test_datetime_initial_with_tz", ATTR_TIMESTAMP: state_without_tz.attributes[ATTR_TIMESTAMP], }, blocking=True, ) state_with_tz_updated = hass.states.get( "input_datetime.test_datetime_initial_with_tz") assert state_with_tz_updated.state == "2020-12-13 10:00:00" assert (state_with_tz_updated.attributes[ATTR_TIMESTAMP] == state_without_tz.attributes[ATTR_TIMESTAMP]) finally: dt_util.set_default_time_zone(ORIG_TIMEZONE)
def to_datetime(obj): """Return a datetime.""" if isinstance(obj, datetime): return obj return dt.as_local(dt.dt.datetime.combine(obj, dt.dt.time.min))
def update(self): """Get the latest system information.""" import psutil if self.type == "disk_use_percent": self._state = psutil.disk_usage(self.argument).percent elif self.type == "disk_use": self._state = round(psutil.disk_usage(self.argument).used / 1024 ** 3, 1) elif self.type == "disk_free": self._state = round(psutil.disk_usage(self.argument).free / 1024 ** 3, 1) elif self.type == "memory_use_percent": self._state = psutil.virtual_memory().percent elif self.type == "memory_use": virtual_memory = psutil.virtual_memory() self._state = round( (virtual_memory.total - virtual_memory.available) / 1024 ** 2, 1 ) elif self.type == "memory_free": self._state = round(psutil.virtual_memory().available / 1024 ** 2, 1) elif self.type == "swap_use_percent": self._state = psutil.swap_memory().percent elif self.type == "swap_use": self._state = round(psutil.swap_memory().used / 1024 ** 2, 1) elif self.type == "swap_free": self._state = round(psutil.swap_memory().free / 1024 ** 2, 1) elif self.type == "processor_use": self._state = round(psutil.cpu_percent(interval=None)) elif self.type == "process": for proc in psutil.process_iter(): try: if self.argument == proc.name(): self._state = STATE_ON return except psutil.NoSuchProcess as err: _LOGGER.warning( "Failed to load process with id: %s, old name: %s", err.pid, err.name, ) self._state = STATE_OFF elif self.type == "network_out" or self.type == "network_in": counters = psutil.net_io_counters(pernic=True) if self.argument in counters: counter = counters[self.argument][IO_COUNTER[self.type]] self._state = round(counter / 1024 ** 2, 1) else: self._state = None elif self.type == "packets_out" or self.type == "packets_in": counters = psutil.net_io_counters(pernic=True) if self.argument in counters: self._state = counters[self.argument][IO_COUNTER[self.type]] else: self._state = None elif ( self.type == "throughput_network_out" or self.type == "throughput_network_in" ): counters = psutil.net_io_counters(pernic=True) if self.argument in counters: counter = counters[self.argument][IO_COUNTER[self.type]] now = dt_util.utcnow() if self._last_value and self._last_value < counter: self._state = round( (counter - self._last_value) / 1000 ** 2 / (now - self._last_update_time).seconds, 3, ) else: self._state = None self._last_update_time = now self._last_value = counter else: self._state = None elif self.type == "ipv4_address" or self.type == "ipv6_address": addresses = psutil.net_if_addrs() if self.argument in addresses: for addr in addresses[self.argument]: if addr.family == IF_ADDRS_FAMILY[self.type]: self._state = addr.address else: self._state = None elif self.type == "last_boot": self._state = dt_util.as_local( dt_util.utc_from_timestamp(psutil.boot_time()) ).isoformat() elif self.type == "load_1m": self._state = os.getloadavg()[0] elif self.type == "load_5m": self._state = os.getloadavg()[1] elif self.type == "load_15m": self._state = os.getloadavg()[2]
async def async_update(self): """Update the state of the sensor.""" import hdate now = dt_util.as_local(dt_util.now()) _LOGGER.debug("Now: %s Timezone = %s", now, now.tzinfo) today = now.date() sunset = dt_util.as_local( get_astral_event_date(self.hass, SUN_EVENT_SUNSET, today)) _LOGGER.debug("Now: %s Sunset: %s", now, sunset) location = hdate.Location(latitude=self.latitude, longitude=self.longitude, timezone=self.timezone, diaspora=self.diaspora) def make_zmanim(date): """Create a Zmanim object.""" return hdate.Zmanim( date=date, location=location, candle_lighting_offset=self.candle_lighting_offset, havdalah_offset=self.havdalah_offset, hebrew=self._hebrew) date = hdate.HDate(today, diaspora=self.diaspora, hebrew=self._hebrew) lagging_date = date # Advance Hebrew date if sunset has passed. # Not all sensors should advance immediately when the Hebrew date # officially changes (i.e. after sunset), hence lagging_date. if now > sunset: date = date.next_day today_times = make_zmanim(today) if today_times.havdalah and now > today_times.havdalah: lagging_date = lagging_date.next_day # Terminology note: by convention in py-libhdate library, "upcoming" # refers to "current" or "upcoming" dates. if self.type == 'date': self._state = date.hebrew_date elif self.type == 'weekly_portion': # Compute the weekly portion based on the upcoming shabbat. self._state = lagging_date.upcoming_shabbat.parasha elif self.type == 'holiday_name': self._state = date.holiday_description elif self.type == 'holyness': self._state = date.holiday_type elif self.type == 'upcoming_shabbat_candle_lighting': times = make_zmanim( lagging_date.upcoming_shabbat.previous_day.gdate) self._state = times.candle_lighting elif self.type == 'upcoming_candle_lighting': times = make_zmanim(lagging_date.upcoming_shabbat_or_yom_tov. first_day.previous_day.gdate) self._state = times.candle_lighting elif self.type == 'upcoming_shabbat_havdalah': times = make_zmanim(lagging_date.upcoming_shabbat.gdate) self._state = times.havdalah elif self.type == 'upcoming_havdalah': times = make_zmanim( lagging_date.upcoming_shabbat_or_yom_tov.last_day.gdate) self._state = times.havdalah elif self.type == 'issur_melacha_in_effect': self._state = make_zmanim(now).issur_melacha_in_effect else: times = make_zmanim(today).zmanim self._state = times[self.type].time() _LOGGER.debug("New value: %s", self._state)
def test_norwegian_case_summer(self): """Test location in Norway where the sun doesn't set in summer.""" self.hass.config.latitude = 69.6 self.hass.config.longitude = 18.8 test_time = self.hass.config.time_zone.localize(datetime( 2010, 6, 1)).astimezone(pytz.UTC) sunrise = dt_util.as_local( get_astral_event_next(self.hass, 'sunrise', dt_util.as_utc(test_time))) sunset = dt_util.as_local( get_astral_event_next(self.hass, 'sunset', dt_util.as_utc(test_time))) config = { 'binary_sensor': [{ 'platform': 'tod', 'name': 'Day', 'after': 'sunrise', 'before': 'sunset' }] } entity_id = 'binary_sensor.day' testtime = test_time with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): setup_component(self.hass, 'binary_sensor', config) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunrise + timedelta(seconds=-1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunrise with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise + timedelta(seconds=1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON self.hass.block_till_done() testtime = sunset + timedelta(seconds=-1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON self.hass.block_till_done() testtime = sunset with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF self.hass.block_till_done() testtime = sunset + timedelta(seconds=1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF
async def test_norwegian_case_summer(hass, freezer, hass_tz_info): """Test location in Norway where the sun doesn't set in summer.""" hass.config.latitude = 69.6 hass.config.longitude = 18.8 hass.config.elevation = 10.0 test_time = datetime(2010, 6, 1, tzinfo=hass_tz_info) sunrise = dt_util.as_local( get_astral_event_next(hass, "sunrise", dt_util.as_utc(test_time)) ) sunset = dt_util.as_local( get_astral_event_next(hass, "sunset", dt_util.as_utc(sunrise)) ) config = { "binary_sensor": [ { "platform": "tod", "name": "Day", "after": "sunrise", "before": "sunset", } ] } entity_id = "binary_sensor.day" freezer.move_to(test_time) await async_setup_component(hass, "binary_sensor", config) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF freezer.move_to(sunrise + timedelta(seconds=-1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF freezer.move_to(sunrise) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON freezer.move_to(sunrise + timedelta(seconds=1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON freezer.move_to(sunset + timedelta(seconds=-1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON freezer.move_to(sunset) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF freezer.move_to(sunset + timedelta(seconds=1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF
def test_from_sunset_to_sunrise(self): """Test period from sunset to sunrise.""" test_time = self.hass.config.time_zone.localize(datetime( 2019, 1, 12)).astimezone(pytz.UTC) sunset = dt_util.as_local( get_astral_event_date(self.hass, 'sunset', test_time)) sunrise = dt_util.as_local( get_astral_event_next(self.hass, 'sunrise', sunset)) # assert sunset == sunrise config = { 'binary_sensor': [{ 'platform': 'tod', 'name': 'Night', 'after': 'sunset', 'before': 'sunrise' }] } entity_id = 'binary_sensor.night' testtime = sunset + timedelta(minutes=-1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): setup_component(self.hass, 'binary_sensor', config) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF testtime = sunset with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunset + timedelta(minutes=1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise + timedelta(minutes=-1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_ON testtime = sunrise with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) self.hass.block_till_done() # assert state == "dupa" assert state.state == STATE_OFF testtime = sunrise + timedelta(minutes=1) with patch('homeassistant.components.tod.binary_sensor.dt_util.utcnow', return_value=testtime): self.hass.bus.fire(ha.EVENT_TIME_CHANGED, {ha.ATTR_NOW: testtime}) self.hass.block_till_done() state = self.hass.states.get(entity_id) assert state.state == STATE_OFF
async def test_sun_offset(hass, freezer, hass_tz_info): """Test sun event with offset.""" test_time = datetime(2019, 1, 12, tzinfo=hass_tz_info) sunrise = dt_util.as_local( get_astral_event_date(hass, "sunrise", dt_util.as_utc(test_time)) + timedelta(hours=-1, minutes=-30) ) sunset = dt_util.as_local( get_astral_event_date(hass, "sunset", dt_util.as_utc(test_time)) + timedelta(hours=1, minutes=30) ) config = { "binary_sensor": [ { "platform": "tod", "name": "Day", "after": "sunrise", "after_offset": "-1:30", "before": "sunset", "before_offset": "1:30", } ] } entity_id = "binary_sensor.day" freezer.move_to(sunrise + timedelta(seconds=-1)) await async_setup_component(hass, "binary_sensor", config) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF freezer.move_to(sunrise) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON freezer.move_to(sunrise + timedelta(seconds=1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON freezer.move_to(sunset + timedelta(seconds=-1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON await hass.async_block_till_done() freezer.move_to(sunset) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF freezer.move_to(sunset + timedelta(seconds=1)) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_OFF test_time = test_time + timedelta(days=1) sunrise = dt_util.as_local( get_astral_event_date(hass, "sunrise", dt_util.as_utc(test_time)) + timedelta(hours=-1, minutes=-30) ) freezer.move_to(sunrise) async_fire_time_changed(hass, dt_util.utcnow()) await hass.async_block_till_done() state = hass.states.get(entity_id) assert state.state == STATE_ON
def media_start_time(self): """Start time the program aired.""" if self._is_standby or self._program is None: return None return dt_util.as_local(self._program.start_time)
def update(self): """Get the latest system information.""" import psutil if self.type == 'disk_use_percent': self._state = psutil.disk_usage(self.argument).percent elif self.type == 'disk_use': self._state = round( psutil.disk_usage(self.argument).used / 1024**3, 1) elif self.type == 'disk_free': self._state = round( psutil.disk_usage(self.argument).free / 1024**3, 1) elif self.type == 'memory_use_percent': self._state = psutil.virtual_memory().percent elif self.type == 'memory_use': self._state = round((psutil.virtual_memory().total - psutil.virtual_memory().available) / 1024**2, 1) elif self.type == 'memory_free': self._state = round(psutil.virtual_memory().available / 1024**2, 1) elif self.type == 'swap_use_percent': self._state = psutil.swap_memory().percent elif self.type == 'swap_use': self._state = round(psutil.swap_memory().used / 1024**3, 1) elif self.type == 'swap_free': self._state = round(psutil.swap_memory().free / 1024**3, 1) elif self.type == 'processor_use': self._state = round(psutil.cpu_percent(interval=None)) elif self.type == 'process': if any(self.argument in l.name() for l in psutil.process_iter()): self._state = STATE_ON else: self._state = STATE_OFF elif self.type == 'network_out' or self.type == 'network_in': counters = psutil.net_io_counters(pernic=True) if self.argument in counters: counter = counters[self.argument][IO_COUNTER[self.type]] self._state = round(counter / 1024**2, 1) else: self._state = STATE_UNKNOWN elif self.type == 'packets_out' or self.type == 'packets_in': counters = psutil.net_io_counters(pernic=True) if self.argument in counters: self._state = counters[self.argument][IO_COUNTER[self.type]] else: self._state = STATE_UNKNOWN elif self.type == 'ipv4_address' or self.type == 'ipv6_address': addresses = psutil.net_if_addrs() if self.argument in addresses: self._state = addresses[self.argument][IF_ADDRS[self.type]][1] else: self._state = STATE_UNKNOWN elif self.type == 'last_boot': self._state = dt_util.as_local( dt_util.utc_from_timestamp( psutil.boot_time())).date().isoformat() elif self.type == 'since_last_boot': self._state = dt_util.utcnow() - dt_util.utc_from_timestamp( psutil.boot_time()) elif self.type == 'load_1m': self._state = os.getloadavg()[0] elif self.type == 'load_5m': self._state = os.getloadavg()[1] elif self.type == 'load_15m': self._state = os.getloadavg()[2]
async def async_update(self): """Update the state of the sensor.""" import hdate now = dt_util.as_local(dt_util.now()) _LOGGER.debug("Now: %s Timezone = %s", now, now.tzinfo) today = now.date() sunset = dt_util.as_local( get_astral_event_date(self.hass, SUN_EVENT_SUNSET, today)) _LOGGER.debug("Now: %s Sunset: %s", now, sunset) if now > sunset: today += timedelta(1) date = hdate.HDate(today, diaspora=self.diaspora, hebrew=self._hebrew) location = hdate.Location(latitude=self.latitude, longitude=self.longitude, timezone=self.timezone, diaspora=self.diaspora) def make_zmanim(date): """Create a Zmanim object.""" return hdate.Zmanim( date=date, location=location, candle_lighting_offset=self.candle_lighting_offset, havdalah_offset=self.havdalah_offset, hebrew=self._hebrew) if self.type == 'date': self._state = date.hebrew_date elif self.type == 'weekly_portion': # Compute the weekly portion based on the upcoming shabbat. self._state = date.upcoming_shabbat.parasha elif self.type == 'holiday_name': self._state = date.holiday_description elif self.type == 'holyness': self._state = date.holiday_type elif self.type == 'upcoming_shabbat_candle_lighting': times = make_zmanim(date.upcoming_shabbat.previous_day.gdate) self._state = times.candle_lighting elif self.type == 'upcoming_candle_lighting': times = make_zmanim( date.upcoming_shabbat_or_yom_tov.first_day.previous_day.gdate) self._state = times.candle_lighting elif self.type == 'upcoming_shabbat_havdalah': times = make_zmanim(date.upcoming_shabbat.gdate) self._state = times.havdalah elif self.type == 'upcoming_havdalah': times = make_zmanim( date.upcoming_shabbat_or_yom_tov.last_day.gdate) self._state = times.havdalah elif self.type == 'issur_melacha_in_effect': self._state = make_zmanim(now).issur_melacha_in_effect else: times = make_zmanim(today).zmanim self._state = times[self.type].time() _LOGGER.debug("New value: %s", self._state)
def _generate_suggestion(hass): """Generate suggestions. Create a dictionary with entity suggestions for time period of the day. """ from homeassistant.components.recorder.models import Events start = monotonic() results = { KEY_MORNING: Counter(), KEY_AFTERNOON: Counter(), KEY_EVENING: Counter(), KEY_NIGHT: Counter(), } week_ago = dt_util.utcnow() - timedelta(days=7) with session_scope(hass=hass) as session: query = ( session.query(Events) .order_by(Events.time_fired) .filter(Events.time_fired > week_ago) ) # Whenever we see a service call for activating a scene or a script, # we don't want to count the services called as result from activating. # We track that by keeping a context blacklist. context_seen = set() for event in query.yield_per(500): entity_ids = None if event.context_id in context_seen: continue if event.event_type == EVENT_CALL_SERVICE: try: event_data = json.loads(event.event_data) except ValueError: continue if not event_data: continue service_data = event_data.get(ATTR_SERVICE_DATA) if not service_data: continue entity_ids = service_data.get(ATTR_ENTITY_ID) if entity_ids is not None and not isinstance(entity_ids, list): entity_ids = [entity_ids] context_seen.add(event.context_id) if entity_ids is None: continue period = _period_from_datetime( dt_util.as_local(event.time_fired)) for entity_id in entity_ids: results[period][entity_id] += 1 _LOGGER.info('Generated suggestions in %.3f seconds', monotonic() - start) return { period: [entity_id for entity_id, count in period_results.most_common(NUM_RESULTS)] for period, period_results in results.items() }
def utc_converter(utc_now: datetime) -> None: """Convert passed in UTC now to local now.""" hass.async_run_hass_job(job, dt_util.as_local(utc_now))
def state(self): """Return the state.""" coordinator_data = self.coordinator.data starman_data = coordinator_data["starman"] launch_data = coordinator_data["next_launch"] latest_launch_data = coordinator_data["latest_launch"] if self._kind == "spacex_next_launch_mission": self._state = launch_data["name"] elif self._kind == "spacex_next_launch_day": self._state = as_local(utc_from_timestamp( launch_data["date_unix"])).strftime("%d-%b-%Y") elif self._kind == "spacex_next_launch_time": self._state = as_local(utc_from_timestamp( launch_data["date_unix"])).strftime("%I:%M %p") elif self._kind == "spacex_next_launch_countdown": if launch_data["tbd"]: self._state = None else: t0_countdown = int(launch_data["date_unix"]) - int(time.time()) self._state = str(datetime.timedelta(seconds=t0_countdown)) elif self._kind == "spacex_next_confirmed_launch_day": if launch_data["tbd"]: self._state = None else: self._state = as_local( utc_from_timestamp( launch_data["date_unix"])).strftime("%d-%b-%Y") elif self._kind == "spacex_next_confirmed_launch_time": if launch_data["tbd"]: self._state = None else: self._state = as_local( utc_from_timestamp( launch_data["date_unix"])).strftime("%I:%M %p") elif self._kind == "spacex_next_launch_site": self._state = launch_data["launch_site"]["full_name"] elif self._kind == "spacex_next_launch_rocket": self._state = launch_data["rocket"]["name"] elif self._kind == "spacex_next_launch_payload": self._state = launch_data["payloads_detail"][0]["name"] elif self._kind == "spacex_latest_launch_mission": self._state = latest_launch_data["name"] elif self._kind == "spacex_latest_launch_day": self._state = as_local( utc_from_timestamp( latest_launch_data["date_unix"])).strftime("%d-%b-%Y") elif self._kind == "spacex_latest_launch_time": self._state = as_local( utc_from_timestamp( latest_launch_data["date_unix"])).strftime("%I:%M %p") elif self._kind == "spacex_latest_launch_site": self._state = latest_launch_data["launch_site"]["full_name"] elif self._kind == "spacex_latest_launch_rocket": self._state = latest_launch_data["rocket"]["name"] elif self._kind == "spacex_latest_launch_payload": self._state = latest_launch_data["payloads_detail"][0]["name"] elif self._kind == "spacex_starman_speed": self._state = int(starman_data["speed_kph"]) self._unit_of_measure = SPEED_KILOMETERS_PER_HOUR elif self._kind == "spacex_starman_distance": self._state = int(starman_data["earth_distance_km"]) self._unit_of_measure = LENGTH_KILOMETERS return self._state