def time_zone(value): """Validate timezone.""" if dt_util.get_time_zone(value) is not None: return value raise vol.Invalid( 'Invalid time zone passed in. Valid options can be found here: ' 'http://en.wikipedia.org/wiki/List_of_tz_database_time_zones')
def test_periodic_task_leaving_dst(self): """Test periodic task behavior when leaving dst.""" tz = dt_util.get_time_zone('Europe/Vienna') dt_util.set_default_time_zone(tz) specific_runs = [] unsub = track_time_change( self.hass, lambda x: specific_runs.append(1), hour=2, minute=30, second=0) self._send_time_changed( tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=False)) self.hass.block_till_done() assert 0 == len(specific_runs) self._send_time_changed( tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=False)) self.hass.block_till_done() assert 1 == len(specific_runs) self._send_time_changed( tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=True)) self.hass.block_till_done() assert 1 == len(specific_runs) self._send_time_changed( tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True)) self.hass.block_till_done() assert 2 == len(specific_runs) unsub()
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" loop = asyncio.new_event_loop() if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant(loop) if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) # FIXME should not be a daemon. Means hass.stop() not called in teardown stop_event = threading.Event() def run_loop(): loop.run_forever() loop.close() stop_event.set() threading.Thread(name="LoopThread", target=run_loop, daemon=True).start() orig_start = hass.start orig_stop = hass.stop @asyncio.coroutine def fake_stop(): yield None def start_hass(): """Helper to start hass.""" with patch.object(hass.loop, 'run_forever', return_value=None): with patch.object(hass, 'async_stop', return_value=fake_stop()): with patch.object(ha, 'async_create_timer', return_value=None): with patch.object(ha, 'async_monitor_worker_pool', return_value=None): orig_start() hass.block_till_done() def stop_hass(): orig_stop() stop_event.wait() hass.start = start_hass hass.stop = stop_hass return hass
def async_test_home_assistant(loop): """Return a Home Assistant object pointing at test config dir.""" loop._thread_ident = threading.get_ident() hass = ha.HomeAssistant(loop) hass.async_track_tasks() hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: yield from loop.run_in_executor(None, loader.prepare, hass) hass.state = ha.CoreState.running # Mock async_start orig_start = hass.async_start @asyncio.coroutine def mock_async_start(): """Start the mocking.""" with patch('homeassistant.core._async_create_timer'): yield from orig_start() hass.async_start = mock_async_start return hass
async def async_setup_platform( hass, config, async_add_entities, discovery_info=None): """Set up the World clock sensor.""" name = config.get(CONF_NAME) time_zone = dt_util.get_time_zone(config.get(CONF_TIME_ZONE)) async_add_entities([WorldClockSensor(time_zone, name)], True)
def setUp(self): """Setup things to be run when tests are started.""" self.hass = get_test_home_assistant() # Set our timezone to CST/Regina so we can check calculations # This keeps UTC-6 all year round dt_util.set_default_time_zone(dt_util.get_time_zone('America/Regina'))
def test_now(self): """Test the now method.""" dt_util.set_default_time_zone(dt_util.get_time_zone(TEST_TIME_ZONE)) self.assertAlmostEqual( dt_util.as_utc(dt_util.now()).replace(tzinfo=None), datetime.utcnow(), delta=timedelta(seconds=1))
def test_set_default_time_zone(self): """Test setting default time zone.""" time_zone = dt_util.get_time_zone(TEST_TIME_ZONE) dt_util.set_default_time_zone(time_zone) # We cannot compare the timezones directly because of DST assert time_zone.zone == dt_util.now().tzinfo.zone
def test_as_utc_with_local_object(self): """Test the UTC time with local object.""" dt_util.set_default_time_zone(dt_util.get_time_zone(TEST_TIME_ZONE)) localnow = dt_util.now() utcnow = dt_util.as_utc(localnow) assert localnow == utcnow assert localnow.tzinfo != utcnow.tzinfo
def setUp(self): """Set up things to be run when tests are started.""" self.hass = get_test_home_assistant() self.time_zone = dt_util.get_time_zone("America/New_York") config = {"sensor": {"platform": "worldclock", "time_zone": "America/New_York"}} self.assertTrue(setup_component(self.hass, "sensor", config))
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 test_timezone_intervals_empty_parameter(self, _): """Test get_interval() without parameters.""" new_tz = dt_util.get_time_zone('America/Edmonton') assert new_tz is not None dt_util.set_default_time_zone(new_tz) device = time_date.TimeDateSensor(self.hass, 'date') next_time = device.get_next_interval() assert (next_time.timestamp() == dt_util.as_timestamp('2017-11-14 00:00:00-07:00'))
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 test_now(self): """Test the now method.""" dt_util.set_default_time_zone(dt_util.get_time_zone(TEST_TIME_ZONE)) assert abs( dt_util.as_utc(dt_util.now()).replace( tzinfo=None ) - datetime.utcnow() ) < timedelta(seconds=1)
def async_test_home_assistant(loop): """Return a Home Assistant object pointing at test config dir.""" global INST_COUNT INST_COUNT += 1 loop._thread_ident = threading.get_ident() hass = ha.HomeAssistant(loop) orig_async_add_job = hass.async_add_job def async_add_job(target, *args): """Add a magic mock.""" if isinstance(target, Mock): return mock_coro(target()) return orig_async_add_job(target, *args) hass.async_add_job = async_add_job hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: yield from loop.run_in_executor(None, loader.prepare, hass) hass.state = ha.CoreState.running # Mock async_start orig_start = hass.async_start @asyncio.coroutine def mock_async_start(): """Start the mocking.""" # 1. We only mock time during tests # 2. We want block_till_done that is called inside stop_track_tasks with patch('homeassistant.core._async_create_timer'), \ patch.object(hass, 'async_stop_track_tasks'): yield from orig_start() hass.async_start = mock_async_start @ha.callback def clear_instance(event): """Clear global instance.""" global INST_COUNT INST_COUNT -= 1 hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, clear_instance) return hass
def async_test_home_assistant(loop): """Return a Home Assistant object pointing at test config dir.""" hass = ha.HomeAssistant(loop) hass.config.async_load = Mock() store = auth.AuthStore(hass) hass.auth = auth.AuthManager(hass, store, {}) ensure_auth_manager_loaded(hass.auth) INSTANCES.append(hass) orig_async_add_job = hass.async_add_job def async_add_job(target, *args): """Add a magic mock.""" if isinstance(target, Mock): return mock_coro(target(*args)) return orig_async_add_job(target, *args) hass.async_add_job = async_add_job hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True hass.config_entries = config_entries.ConfigEntries(hass, {}) hass.config_entries._entries = [] hass.config_entries._store._async_ensure_stop_listener = lambda: None hass.state = ha.CoreState.running # Mock async_start orig_start = hass.async_start @asyncio.coroutine def mock_async_start(): """Start the mocking.""" # We only mock time during tests and we want to track tasks with patch('homeassistant.core._async_create_timer'), \ patch.object(hass, 'async_stop_track_tasks'): yield from orig_start() hass.async_start = mock_async_start @ha.callback def clear_instance(event): """Clear global instance.""" INSTANCES.remove(hass) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, clear_instance) return hass
def set_time_zone(time_zone_str): """ Helper method to set time zone in HA. """ if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error("Received invalid time zone %s", time_zone_str)
def test_timezone_intervals(self): """Test date sensor behavior in a timezone besides UTC.""" new_tz = dt_util.get_time_zone('America/New_York') assert new_tz is not None dt_util.set_default_time_zone(new_tz) device = time_date.TimeDateSensor(self.hass, 'date') now = dt_util.utc_from_timestamp(50000) next_time = device.get_next_interval(now) # start of local day in EST was 18000.0 # so the second day was 18000 + 86400 assert next_time.timestamp() == 104400 new_tz = dt_util.get_time_zone('America/Edmonton') assert new_tz is not None dt_util.set_default_time_zone(new_tz) now = dt_util.parse_datetime('2017-11-13 19:47:19-07:00') device = time_date.TimeDateSensor(self.hass, 'date') next_time = device.get_next_interval(now) assert (next_time.timestamp() == dt_util.as_timestamp('2017-11-14 00:00:00-07:00'))
def set_time_zone(time_zone_str: Optional[str]) -> None: """Help to set the time zone.""" if time_zone_str is None: return time_zone = date_util.get_time_zone(time_zone_str) if time_zone: hac.time_zone = time_zone date_util.set_default_time_zone(time_zone) else: _LOGGER.error("Received invalid time zone %s", time_zone_str)
def setUp(self): """Set up things to be run when tests are started.""" self.hass = get_test_home_assistant() self.time_zone = dt_util.get_time_zone('America/New_York') config = { 'sensor': { 'platform': 'worldclock', 'time_zone': 'America/New_York', } } assert setup_component(self.hass, 'sensor', config)
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Worldclock sensor.""" try: time_zone = dt_util.get_time_zone(config.get('time_zone')) except AttributeError: _LOGGER.error("time_zone in platform configuration is missing.") return False if time_zone is None: _LOGGER.error("Timezone '%s' is not valid.", config.get('time_zone')) return False add_devices([WorldClockSensor( time_zone, config.get('name', DEFAULT_NAME) )])
def test_jewish_calendar_sensor(self, time, tzname, latitude, longitude, language, sensor, diaspora, result): """Test Jewish calendar sensor output.""" tz = get_time_zone(tzname) set_default_time_zone(tz) test_time = tz.localize(time) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor( name='test', language=language, sensor_type=sensor, latitude=latitude, longitude=longitude, timezone=tz, diaspora=diaspora) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe( sensor.async_update(), self.hass.loop).result() assert sensor.state == result
def test_find_next_time_expression_time_dst(self): """Test daylight saving time for find_next_time_expression_time.""" tz = dt_util.get_time_zone('Europe/Vienna') dt_util.set_default_time_zone(tz) def find(dt, hour, minute, second): """Call test_find_next_time_expression_time.""" seconds = dt_util.parse_time_expression(second, 0, 59) minutes = dt_util.parse_time_expression(minute, 0, 59) hours = dt_util.parse_time_expression(hour, 0, 23) return dt_util.find_next_time_expression_time( dt, seconds, minutes, hours) # Entering DST, clocks are rolled forward assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == \ find(tz.localize(datetime(2018, 3, 25, 1, 50, 0)), 2, 30, 0) assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == \ find(tz.localize(datetime(2018, 3, 25, 3, 50, 0)), 2, 30, 0) assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == \ find(tz.localize(datetime(2018, 3, 26, 1, 50, 0)), 2, 30, 0) # Leaving DST, clocks are rolled back assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=False) == \ find(tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=False), 2, 30, 0) assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=False) == \ find(tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True), 2, 30, 0) assert tz.localize(datetime(2018, 10, 28, 4, 30, 0), is_dst=False) == \ find(tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True), 4, 30, 0) assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=True) == \ find(tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=True), 2, 30, 0) assert tz.localize(datetime(2018, 10, 29, 2, 30, 0)) == \ find(tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=False), 2, 30, 0)
def test_issur_melacha_sensor(self, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result): """Test Issur Melacha sensor output.""" time_zone = get_time_zone(tzname) set_default_time_zone(time_zone) test_time = time_zone.localize(now) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor( name='test', language='english', sensor_type='issur_melacha_in_effect', latitude=latitude, longitude=longitude, timezone=time_zone, diaspora=diaspora, havdalah_offset=havdalah, candle_lighting_offset=candle_lighting) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe( sensor.async_update(), self.hass.loop).result() assert sensor.state == result
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant() if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.temperature_unit = TEMP_CELCIUS if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) return hass
def test_find_next_time_expression_time_leave_dst_chicago_into_the_fold_same_time(): """Test leaving daylight saving time for find_next_time_expression_time.""" tz = dt_util.get_time_zone("America/Chicago") dt_util.set_default_time_zone(tz) # Leaving DST, clocks are rolled back # Find the same time inside the fold hour_minute_second = (1, 30, 1) test_time = datetime(2021, 11, 7, *hour_minute_second, tzinfo=tz, fold=0) matching_hours, matching_minutes, matching_seconds = _get_matches( *hour_minute_second ) next_time = dt_util.find_next_time_expression_time( test_time, matching_seconds, matching_minutes, matching_hours ) assert next_time == datetime(2021, 11, 7, *hour_minute_second, tzinfo=tz, fold=1) assert next_time.fold == 0 assert dt_util.as_utc(next_time) == datetime( 2021, 11, 7, 6, 30, 1, tzinfo=dt_util.UTC )
def test_auto_purge(hass_recorder): """Test saving and restoring a state.""" hass = hass_recorder() original_tz = dt_util.DEFAULT_TIME_ZONE tz = dt_util.get_time_zone("Europe/Copenhagen") dt_util.set_default_time_zone(tz) test_time = tz.localize(datetime(2020, 1, 1, 4, 12, 0)) with patch("homeassistant.components.recorder.purge.purge_old_data" ) as purge_old_data: for delta in (-1, 0, 1): hass.bus.fire(EVENT_TIME_CHANGED, {ATTR_NOW: test_time + timedelta(seconds=delta)}) hass.block_till_done() hass.data[DATA_INSTANCE].block_till_done() assert len(purge_old_data.mock_calls) == 1 dt_util.set_default_time_zone(original_tz)
def get_test_home_assistant(num_threads=None): """Return a Home Assistant object pointing at test config dir.""" if num_threads: orig_num_threads = ha.MIN_WORKER_THREAD ha.MIN_WORKER_THREAD = num_threads hass = ha.HomeAssistant() if num_threads: ha.MIN_WORKER_THREAD = orig_num_threads hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM if 'custom_components.test' not in loader.AVAILABLE_COMPONENTS: loader.prepare(hass) return hass
def test_find_next_time_expression_time_dst(): """Test daylight saving time for find_next_time_expression_time.""" tz = dt_util.get_time_zone("Europe/Vienna") dt_util.set_default_time_zone(tz) def find(dt, hour, minute, second): """Call test_find_next_time_expression_time.""" seconds = dt_util.parse_time_expression(second, 0, 59) minutes = dt_util.parse_time_expression(minute, 0, 59) hours = dt_util.parse_time_expression(hour, 0, 23) return dt_util.find_next_time_expression_time(dt, seconds, minutes, hours) # Entering DST, clocks are rolled forward assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == find( tz.localize(datetime(2018, 3, 25, 1, 50, 0)), 2, 30, 0) assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == find( tz.localize(datetime(2018, 3, 25, 3, 50, 0)), 2, 30, 0) assert tz.localize(datetime(2018, 3, 26, 2, 30, 0)) == find( tz.localize(datetime(2018, 3, 26, 1, 50, 0)), 2, 30, 0) # Leaving DST, clocks are rolled back assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=False) == find( tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=False), 2, 30, 0) assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=False) == find( tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True), 2, 30, 0) assert tz.localize(datetime(2018, 10, 28, 4, 30, 0), is_dst=False) == find( tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=True), 4, 30, 0) assert tz.localize(datetime(2018, 10, 28, 2, 30, 0), is_dst=True) == find( tz.localize(datetime(2018, 10, 28, 2, 5, 0), is_dst=True), 2, 30, 0) assert tz.localize(datetime(2018, 10, 29, 2, 30, 0)) == find( tz.localize(datetime(2018, 10, 28, 2, 55, 0), is_dst=False), 2, 30, 0)
def test_shabbat_times_sensor(self, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result): """Test sensor output for upcoming shabbat/yomtov times.""" time_zone = get_time_zone(tzname) set_default_time_zone(time_zone) test_time = time_zone.localize(now) for sensor_type, value in result.items(): if isinstance(value, dt): result[sensor_type] = time_zone.localize(value) self.hass.config.latitude = latitude self.hass.config.longitude = longitude if ('upcoming_shabbat_candle_lighting' in result and 'upcoming_candle_lighting' not in result): result['upcoming_candle_lighting'] = \ result['upcoming_shabbat_candle_lighting'] if ('upcoming_shabbat_havdalah' in result and 'upcoming_havdalah' not in result): result['upcoming_havdalah'] = result['upcoming_shabbat_havdalah'] for sensor_type, result_value in result.items(): language = 'english' if sensor_type.startswith('hebrew_'): language = 'hebrew' sensor_type = sensor_type.replace('hebrew_', '') sensor = JewishCalSensor( name='test', language=language, sensor_type=sensor_type, latitude=latitude, longitude=longitude, timezone=time_zone, diaspora=diaspora, havdalah_offset=havdalah, candle_lighting_offset=candle_lighting) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe( sensor.async_update(), self.hass.loop).result() assert sensor.state == result_value, "Value for {}".format( sensor_type)
async def async_update(self) -> None: """Retrieve latest state.""" when = dt.now() _state: TrainStop | None = None if self._time: departure_day = next_departuredate(self._weekday) when = datetime.combine( departure_day, self._time, dt.get_time_zone(self.hass.config.time_zone)) try: if self._time: _state = await self._train_api.async_get_train_stop( self._from_station, self._to_station, when) else: _state = await self._train_api.async_get_next_train_stop( self._from_station, self._to_station, when) except ValueError as output_error: _LOGGER.error("Departure %s encountered a problem: %s", when, output_error) if not _state: self._attr_available = False self._attr_native_value = None self._attr_extra_state_attributes = {} return self._attr_available = True # The original datetime doesn't provide a timezone so therefore attaching it here. self._attr_native_value = dt.as_utc(_state.advertised_time_at_location) if _state.time_at_location: self._attr_native_value = dt.as_utc(_state.time_at_location) if _state.estimated_time_at_location: self._attr_native_value = dt.as_utc( _state.estimated_time_at_location) self._update_attributes(_state)
def update(self): """Update the data for the sensor.""" time_zone = dt_util.get_time_zone(self.hass.config.time_zone) start = get_date(time_zone) end = get_date(time_zone, self.days) try: res = requests.get( ENDPOINTS[self.type].format(self.ssl, self.host, self.port, self.urlbase, start, end), headers={"X-Api-Key": self.apikey}, timeout=10, ) except OSError: _LOGGER.warning("Host %s is not available", self.host) self._available = False self._state = None return if res.status_code == HTTP_OK: if self.type in ["upcoming", "movies", "commands"]: self.data = res.json() self._state = len(self.data) elif self.type == "diskspace": # If included paths are not provided, use all data if self.included == []: self.data = res.json() else: # Filter to only show lists that are included self.data = list( filter(lambda x: x["path"] in self.included, res.json())) self._state = "{:.2f}".format( to_unit(sum(data["freeSpace"] for data in self.data), self._unit)) elif self.type == "status": self.data = res.json() self._state = self.data["version"] self._available = True
async def test_jewish_calendar_sensor(hass, now, tzname, latitude, longitude, language, sensor, diaspora, result): """Test Jewish calendar sensor output.""" time_zone = dt_util.get_time_zone(tzname) test_time = time_zone.localize(now) hass.config.time_zone = time_zone hass.config.latitude = latitude hass.config.longitude = longitude with alter_time(test_time): assert await async_setup_component( hass, jewish_calendar.DOMAIN, { "jewish_calendar": { "name": "test", "language": language, "diaspora": diaspora, } }, ) await hass.async_block_till_done() future = dt_util.utcnow() + timedelta(seconds=30) async_fire_time_changed(hass, future) await hass.async_block_till_done() result = (dt_util.as_utc(time_zone.localize(result)) if isinstance( result, dt) else result) sensor_object = hass.states.get(f"sensor.test_{sensor}") assert sensor_object.state == str(result) if sensor == "holiday": assert sensor_object.attributes.get("id") == "rosh_hashana_i" assert sensor_object.attributes.get("type") == "YOM_TOV" assert sensor_object.attributes.get("type_id") == 1
def __init__(self, latitude=None, longitude=None, mode=FORECAST_MODE_HOURLY, params=None): """Initialize the data object.""" params = params or {} _LOGGER.debug('Place coordinates: %s, %s', latitude, longitude) _LOGGER.debug('Forecast mode: %s', mode) self._mode = mode self._cache = Cache(params) if params.get( 'cache_dir') is not None else None self._city_id = self._get_city_id(latitude, longitude) _LOGGER.debug('Nearest city ID: %s', self._city_id) self._current = {} self._forecast = [] self._timezone = dt_util.get_time_zone( params.get('timezone')) if params.get( 'timezone') is not None else dt_util.DEFAULT_TIME_ZONE
def test_issur_melacha_sensor(self, now, candle_lighting, havdalah, diaspora, tzname, latitude, longitude, result): """Test Issur Melacha sensor output.""" time_zone = get_time_zone(tzname) set_default_time_zone(time_zone) test_time = time_zone.localize(now) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor(name='test', language='english', sensor_type='issur_melacha_in_effect', latitude=latitude, longitude=longitude, timezone=time_zone, diaspora=diaspora, havdalah_offset=havdalah, candle_lighting_offset=candle_lighting) sensor.hass = self.hass with patch('homeassistant.util.dt.now', return_value=test_time): run_coroutine_threadsafe(sensor.async_update(), self.hass.loop).result() assert sensor.state == result
async def test_data_manager_update_sleep_date_range( data_manager: WithingsDataManager, ) -> None: """Test method.""" patch_time_zone = patch( "homeassistant.util.dt.DEFAULT_TIME_ZONE", new=dt.get_time_zone("America/Belize"), ) with patch_time_zone: update_start_time = dt.now() await data_manager.update_sleep() call_args = data_manager.api.sleep_get.call_args_list[0][1] startdate = call_args.get("startdate") enddate = call_args.get("enddate") assert startdate.tzname() == "CST" assert enddate.tzname() == "CST" assert startdate.tzname() == "CST" assert update_start_time < enddate assert enddate < update_start_time + timedelta(seconds=1) assert enddate > startdate
def test_auto_purge(hass_recorder): """Test saving and restoring a state.""" hass = hass_recorder() original_tz = dt_util.DEFAULT_TIME_ZONE tz = dt_util.get_time_zone("Europe/Copenhagen") dt_util.set_default_time_zone(tz) now = dt_util.utcnow() test_time = tz.localize(datetime(now.year + 1, 1, 1, 4, 12, 0)) async_fire_time_changed(hass, test_time) with patch("homeassistant.components.recorder.purge.purge_old_data", return_value=True) as purge_old_data: for delta in (-1, 0, 1): async_fire_time_changed(hass, test_time + timedelta(seconds=delta)) hass.block_till_done() hass.data[DATA_INSTANCE].block_till_done() assert len(purge_old_data.mock_calls) == 1 dt_util.set_default_time_zone(original_tz)
def test_jewish_calendar_sensor(self, cur_time, tzname, latitude, longitude, language, sensor, diaspora, result): """Test Jewish calendar sensor output.""" time_zone = get_time_zone(tzname) set_default_time_zone(time_zone) test_time = time_zone.localize(cur_time) self.hass.config.latitude = latitude self.hass.config.longitude = longitude sensor = JewishCalSensor( name="test", language=language, sensor_type=sensor, latitude=latitude, longitude=longitude, timezone=time_zone, diaspora=diaspora, ) sensor.hass = self.hass with patch("homeassistant.util.dt.now", return_value=test_time): run_coroutine_threadsafe(sensor.async_update(), self.hass.loop).result() assert sensor.state == result
async def test_set_datetime_3(hass): """Test set_datetime method using timestamp.""" await async_setup_component( hass, DOMAIN, {DOMAIN: { "test_datetime": { "has_time": True, "has_date": True } }}) entity_id = "input_datetime.test_datetime" dt_obj = datetime.datetime(2017, 9, 7, 19, 46, 30, tzinfo=dt_util.get_time_zone( hass.config.time_zone)) await async_set_timestamp(hass, entity_id, dt_util.as_utc(dt_obj).timestamp()) state = hass.states.get(entity_id) assert state.state == dt_obj.strftime(FMT_DATETIME) assert state.attributes["has_time"] assert state.attributes["has_date"] assert state.attributes["year"] == 2017 assert state.attributes["month"] == 9 assert state.attributes["day"] == 7 assert state.attributes["hour"] == 19 assert state.attributes["minute"] == 46 assert state.attributes["second"] == 30 assert state.attributes["timestamp"] == dt_obj.timestamp()
async def test_dst(hass, freezer, hass_tz_info): """Test sun event with offset.""" hass.config.time_zone = "CET" dt_util.set_default_time_zone(dt_util.get_time_zone("CET")) test_time = datetime(2019, 3, 30, 3, 0, 0, tzinfo=hass_tz_info) config = { "binary_sensor": [ {"platform": "tod", "name": "Day", "after": "2:30", "before": "2:40"} ] } # Test DST: # after 2019-03-30 03:00 CET the next update should ge scheduled # at 3:30 not 2:30 local time entity_id = "binary_sensor.day" freezer.move_to(test_time) 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.attributes["after"] == "2019-03-31T03:30:00+02:00" assert state.attributes["before"] == "2019-03-31T03:40:00+02:00" assert state.attributes["next_update"] == "2019-03-31T03:30:00+02:00" assert state.state == STATE_OFF
def __init__(self, latitude=None, longitude=None, mode=FORECAST_MODE_HOURLY, params=None): """Initialize the data object.""" params = params or {} params["domain"] = DOMAIN _LOGGER.debug("Place coordinates: %s, %s", latitude, longitude) _LOGGER.debug("Forecast mode: %s", mode) self._mode = mode self._cache = Cache(params) if params.get( "cache_dir") is not None else None self._city_id = self._get_city_id(latitude, longitude) _LOGGER.debug("Nearest city ID: %s", self._city_id) self._current = {} self._forecast = [] self._timezone = (dt_util.get_time_zone(params.get("timezone")) if params.get("timezone") is not None else dt_util.DEFAULT_TIME_ZONE)
def test_find_next_time_expression_time_leave_dst_chicago_inside_the_fold_ahead_10_min(): """Test leaving daylight saving time for find_next_time_expression_time.""" tz = dt_util.get_time_zone("America/Chicago") dt_util.set_default_time_zone(tz) # Leaving DST, clocks are rolled back # Find 10m later while we are in the fold # Start at 01:30:01 fold=0 # Reach to 01:40:01 fold=1 hour_minute_second = (1, 40, 1) test_time = datetime(2021, 11, 7, 1, 30, 1, tzinfo=tz, fold=1) matching_hours, matching_minutes, matching_seconds = _get_matches( *hour_minute_second ) next_time = dt_util.find_next_time_expression_time( test_time, matching_seconds, matching_minutes, matching_hours ) assert next_time == datetime(2021, 11, 7, *hour_minute_second, tzinfo=tz, fold=1) assert next_time.fold == 1 # time is ambiguous assert dt_util.as_utc(next_time) == datetime( 2021, 11, 7, 7, 40, 1, tzinfo=dt_util.UTC )
def test_find_next_time_expression_time_leave_dst_chicago_past_the_fold_ahead_2_hour_10_min(): """Test leaving daylight saving time for find_next_time_expression_time.""" tz = dt_util.get_time_zone("America/Chicago") dt_util.set_default_time_zone(tz) # Leaving DST, clocks are rolled back # Find 1h 10m after into the fold # Start at 01:30:01 fold=0 # Reach to 02:20:01 past the fold hour_minute_second = (2, 20, 1) test_time = datetime(2021, 11, 7, 1, 30, 1, tzinfo=tz, fold=0) matching_hours, matching_minutes, matching_seconds = _get_matches( *hour_minute_second ) next_time = dt_util.find_next_time_expression_time( test_time, matching_seconds, matching_minutes, matching_hours ) assert next_time == datetime(2021, 11, 7, *hour_minute_second, tzinfo=tz, fold=1) assert next_time.fold == 0 # Time is no longer ambiguous assert dt_util.as_utc(next_time) == datetime( 2021, 11, 7, 8, 20, 1, tzinfo=dt_util.UTC )
def test_get_time_zone_retrieves_valid_time_zone(self): """Test getting a time zone.""" time_zone = dt_util.get_time_zone(TEST_TIME_ZONE) self.assertIsNotNone(time_zone) self.assertEqual(TEST_TIME_ZONE, time_zone.zone)
def test_get_time_zone_returns_none_for_garbage_time_zone(self): """Test getting a non existing time zone.""" time_zone = dt_util.get_time_zone("Non existing time zone") self.assertIsNone(time_zone)
def tearDown(self): """Stop everything that was started.""" dt_util.set_default_time_zone(dt_util.get_time_zone('UTC')) self.hass.stop()
async def test_multi_sensor_migration( hass, caplog, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker): """Test tariff migration when there are >1 old sensors.""" entity_reg = mock_registry(hass) hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid") uid_1 = "discrimination" uid_2 = "normal" old_conf_1 = {CONF_NAME: "test_pvpc_1", ATTR_TARIFF: uid_1} old_conf_2 = {CONF_NAME: "test_pvpc_2", ATTR_TARIFF: uid_2} config_entry_1 = MockConfigEntry(domain=DOMAIN, data=old_conf_1, unique_id=uid_1) config_entry_1.add_to_hass(hass) entity1 = entity_reg.async_get_or_create( domain="sensor", platform=DOMAIN, unique_id=uid_1, config_entry=config_entry_1, suggested_object_id="test_pvpc_1", ) config_entry_2 = MockConfigEntry(domain=DOMAIN, data=old_conf_2, unique_id=uid_2) config_entry_2.add_to_hass(hass) entity2 = entity_reg.async_get_or_create( domain="sensor", platform=DOMAIN, unique_id=uid_2, config_entry=config_entry_2, suggested_object_id="test_pvpc_2", ) assert len(hass.config_entries.async_entries(DOMAIN)) == 2 assert len(entity_reg.entities) == 2 mock_data = { "return_time": datetime(2019, 10, 27, 20, tzinfo=date_util.UTC) } def mock_now(): return mock_data["return_time"] caplog.clear() with caplog.at_level(logging.WARNING): with patch("homeassistant.util.dt.utcnow", new=mock_now): assert await hass.config_entries.async_setup( config_entry_1.entry_id) assert len(caplog.messages) == 2 # check migration with removal of extra sensors assert len(entity_reg.entities) == 1 assert entity1.entity_id in entity_reg.entities assert entity2.entity_id not in entity_reg.entities current_entries = hass.config_entries.async_entries(DOMAIN) assert len(current_entries) == 1 migrated_entry = current_entries[0] assert migrated_entry.version == 1 assert migrated_entry.data[ATTR_POWER] == migrated_entry.data[ ATTR_POWER_P3] assert migrated_entry.data[ATTR_TARIFF] == TARIFFS[0] await hass.async_block_till_done() assert pvpc_aioclient_mock.call_count == 2
def setUp(self): """Set up things to be run when tests are started.""" self.hass = get_test_home_assistant() self.time_zone = dt_util.get_time_zone("America/New_York")
) import homeassistant.helpers.config_validation as cv from homeassistant.util import Throttle, dt as dt_util _LOGGER = logging.getLogger(__name__) ATTR_STATION = "station" ATTR_UPDATED = "updated" ATTRIBUTION = "Data provided by ZAMG" CONF_STATION_ID = "station_id" DEFAULT_NAME = "zamg" MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=10) VIENNA_TIME_ZONE = dt_util.get_time_zone("Europe/Vienna") DTypeT = Union[Type[int], Type[float], Type[str]] @dataclass class ZamgRequiredKeysMixin: """Mixin for required keys.""" col_heading: str dtype: DTypeT @dataclass class ZamgSensorEntityDescription(SensorEntityDescription, ZamgRequiredKeysMixin):
def test_get_time_zone_returns_none_for_garbage_time_zone(self): """Test getting a non existing time zone.""" time_zone = dt_util.get_time_zone("Non existing time zone") assert time_zone is None
def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Worldclock sensor.""" name = config.get(CONF_NAME) time_zone = dt_util.get_time_zone(config.get(CONF_TIME_ZONE)) add_devices([WorldClockSensor(time_zone, name)])
async def test_sensor_availability(hass, caplog, legacy_patchable_time, pvpc_aioclient_mock: AiohttpClientMocker): """Test sensor availability and handling of cloud access.""" hass.config.time_zone = dt_util.get_time_zone("Europe/Madrid") config_entry = MockConfigEntry(domain=DOMAIN, data={ CONF_NAME: "test_dst", ATTR_TARIFF: "discrimination" }) config_entry.add_to_hass(hass) assert len(hass.config_entries.async_entries(DOMAIN)) == 1 mock_data = { "return_time": datetime(2019, 10, 27, 20, 0, 0, tzinfo=date_util.UTC) } def mock_now(): return mock_data["return_time"] with patch("homeassistant.util.dt.utcnow", new=mock_now): assert await hass.config_entries.async_setup(config_entry.entry_id) # check migration current_entries = hass.config_entries.async_entries(DOMAIN) assert len(current_entries) == 1 migrated_entry = current_entries[0] assert migrated_entry.version == 1 assert migrated_entry.data[ATTR_POWER] == migrated_entry.data[ ATTR_POWER_P3] assert migrated_entry.data[ATTR_TARIFF] == TARIFFS[0] await hass.async_block_till_done() caplog.clear() assert pvpc_aioclient_mock.call_count == 2 await _process_time_step(hass, mock_data, "price_21h", 0.13896) await _process_time_step(hass, mock_data, "price_22h", 0.06893) assert pvpc_aioclient_mock.call_count == 4 await _process_time_step(hass, mock_data, "price_23h", 0.06935) assert pvpc_aioclient_mock.call_count == 5 # sensor has no more prices, state is "unavailable" from now on await _process_time_step(hass, mock_data, value="unavailable") await _process_time_step(hass, mock_data, value="unavailable") num_errors = sum(1 for x in caplog.records if x.levelno == logging.ERROR and "unknown job listener" not in x.msg) num_warnings = sum(1 for x in caplog.records if x.levelno == logging.WARNING) assert num_warnings == 1 assert num_errors == 0 assert pvpc_aioclient_mock.call_count == 9 # check that it is silent until it becomes available again caplog.clear() with caplog.at_level(logging.WARNING): # silent mode for _ in range(21): await _process_time_step(hass, mock_data, value="unavailable") assert pvpc_aioclient_mock.call_count == 30 assert len(caplog.messages) == 0 # warning about data access recovered await _process_time_step(hass, mock_data, value="unavailable") assert pvpc_aioclient_mock.call_count == 31 assert len(caplog.messages) == 1 assert caplog.records[0].levelno == logging.WARNING # working ok again await _process_time_step(hass, mock_data, "price_00h", value=0.06821) assert pvpc_aioclient_mock.call_count == 32 await _process_time_step(hass, mock_data, "price_01h", value=0.06627) assert pvpc_aioclient_mock.call_count == 33 assert len(caplog.messages) == 1 assert caplog.records[0].levelno == logging.WARNING
def teardown_method(self, method): """Stop everything that was started.""" self.hass.stop() # Reset the default timezone, so we don't affect other tests set_default_time_zone(get_time_zone('UTC'))
MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1) MAX_LIST = 20 MAX_TIME_OFFSET = 360 ICON = "mdi:bus" ATTR_DEPARTURE = "departure" ATTR_LINE = "line" ATTR_ORIGIN = "origin" ATTR_DIRECTION = "direction" ATTR_TYPE = "type" ATTR_DELAY = "delay" ATTR_NEXT = "next" PARALLEL_UPDATES = 0 BERLIN_TIME_ZONE = get_time_zone("Europe/Berlin") _LOGGER = logging.getLogger(__name__) async def async_setup_entry(hass, config_entry, async_add_devices): """Set up the sensor platform.""" hub = hass.data[DOMAIN][config_entry.entry_id] session = aiohttp_client.async_get_clientsession(hass) sensor = HVVDepartureSensor(hass, config_entry, session, hub) async_add_devices([sensor], True) class HVVDepartureSensor(SensorEntity):
async def async_test_home_assistant(loop): """Return a Home Assistant object pointing at test config dir.""" hass = ha.HomeAssistant(loop) store = auth_store.AuthStore(hass) hass.auth = auth.AuthManager(hass, store, {}, {}) ensure_auth_manager_loaded(hass.auth) INSTANCES.append(hass) orig_async_add_job = hass.async_add_job orig_async_add_executor_job = hass.async_add_executor_job orig_async_create_task = hass.async_create_task def async_add_job(target, *args): """Add job.""" if isinstance(target, Mock): return mock_coro(target(*args)) return orig_async_add_job(target, *args) def async_add_executor_job(target, *args): """Add executor job.""" if isinstance(target, Mock): return mock_coro(target(*args)) return orig_async_add_executor_job(target, *args) def async_create_task(coroutine): """Create task.""" if isinstance(coroutine, Mock): return mock_coro() return orig_async_create_task(coroutine) hass.async_add_job = async_add_job hass.async_add_executor_job = async_add_executor_job hass.async_create_task = async_create_task hass.config.location_name = 'test home' hass.config.config_dir = get_test_config_dir() hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 hass.config.time_zone = date_util.get_time_zone('US/Pacific') hass.config.units = METRIC_SYSTEM hass.config.skip_pip = True hass.config_entries = config_entries.ConfigEntries(hass, {}) hass.config_entries._entries = [] hass.config_entries._store._async_ensure_stop_listener = lambda: None hass.state = ha.CoreState.running # Mock async_start orig_start = hass.async_start async def mock_async_start(): """Start the mocking.""" # We only mock time during tests and we want to track tasks with patch('homeassistant.core._async_create_timer'), \ patch.object(hass, 'async_stop_track_tasks'): await orig_start() hass.async_start = mock_async_start @ha.callback def clear_instance(event): """Clear global instance.""" INSTANCES.remove(hass) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, clear_instance) return hass
MATCH_ALL, __version__, ) import homeassistant.core as ha from homeassistant.exceptions import ( InvalidEntityFormatError, InvalidStateError, MaxLengthExceeded, ServiceNotFound, ) import homeassistant.util.dt as dt_util from homeassistant.util.unit_system import METRIC_SYSTEM from tests.common import async_capture_events, async_mock_service PST = dt_util.get_time_zone("America/Los_Angeles") def test_split_entity_id(): """Test split_entity_id.""" assert ha.split_entity_id("domain.object_id") == ["domain", "object_id"] def test_async_add_hass_job_schedule_callback(): """Test that we schedule coroutines and add jobs to the job pool.""" hass = MagicMock() job = MagicMock() ha.HomeAssistant.async_add_hass_job(hass, ha.HassJob(ha.callback(job))) assert len(hass.loop.call_soon.mock_calls) == 1 assert len(hass.loop.create_task.mock_calls) == 0
async def async_check_date_and_time(self): """Warns if camera and system date not synced.""" _LOGGER.debug("Setting up the ONVIF device management service") devicemgmt = self._camera.create_devicemgmt_service() _LOGGER.debug("Retrieving current camera date/time") try: system_date = dt_util.utcnow() device_time = await devicemgmt.GetSystemDateAndTime() if not device_time: _LOGGER.debug( """Couldn't get camera '%s' date/time. GetSystemDateAndTime() return null/empty""", self._name, ) return if device_time.UTCDateTime: tzone = dt_util.UTC cdate = device_time.UTCDateTime else: tzone = (dt_util.get_time_zone(device_time.TimeZone) or dt_util.DEFAULT_TIME_ZONE) cdate = device_time.LocalDateTime if cdate is None: _LOGGER.warning("Could not retrieve date/time on this camera") else: cam_date = dt.datetime( cdate.Date.Year, cdate.Date.Month, cdate.Date.Day, cdate.Time.Hour, cdate.Time.Minute, cdate.Time.Second, 0, tzone, ) cam_date_utc = cam_date.astimezone(dt_util.UTC) _LOGGER.debug("TimeZone for date/time: %s", tzone) _LOGGER.debug("Camera date/time: %s", cam_date) _LOGGER.debug("Camera date/time in UTC: %s", cam_date_utc) _LOGGER.debug("System date/time: %s", system_date) dt_diff = cam_date - system_date dt_diff_seconds = dt_diff.total_seconds() if dt_diff_seconds > 5: _LOGGER.warning( "The date/time on the camera (UTC) is '%s', " "which is different from the system '%s', " "this could lead to authentication issues", cam_date_utc, system_date, ) except ServerDisconnectedError as err: _LOGGER.warning("Couldn't get camera '%s' date/time. Error: %s", self._name, err)
def _update_member(self, m, name): name = name.replace(',', '_').replace('-', '_') dev_id = slugify(self._prefix + name) prev_seen, reported = self._dev_data.get(dev_id, (None, False)) loc = m.get('location') try: last_seen = utc_from_ts(loc.get('timestamp')) except AttributeError: last_seen = None if self._max_update_wait: update = last_seen or prev_seen or self._started overdue = dt_util.utcnow() - update > self._max_update_wait if overdue and not reported: self._hass.bus.fire( 'life360_update_overdue', {'entity_id': DT_ENTITY_ID_FORMAT.format(dev_id)}) reported = True elif not overdue and reported: self._hass.bus.fire( 'life360_update_restored', { 'entity_id': DT_ENTITY_ID_FORMAT.format(dev_id), 'wait': str(last_seen - (prev_seen or self._started)).split('.')[0] }) reported = False self._dev_data[dev_id] = last_seen or prev_seen, reported if not loc: err_msg = m['issues']['title'] if err_msg: if m['issues']['dialog']: err_msg += ': ' + m['issues']['dialog'] else: err_msg = 'Location information missing' self._err(dev_id, err_msg) return if last_seen and (not prev_seen or last_seen > prev_seen): lat = loc.get('latitude') lon = loc.get('longitude') gps_accuracy = loc.get('accuracy') try: lat = float(lat) lon = float(lon) # Life360 reports accuracy in feet, but Device Tracker expects # gps_accuracy in meters. gps_accuracy = round( convert(float(gps_accuracy), LENGTH_FEET, LENGTH_METERS)) except (TypeError, ValueError): self._err( dev_id, 'GPS data invalid: {}, {}, {}'.format( lat, lon, gps_accuracy)) return self._ok(dev_id) msg = 'Updating {}'.format(dev_id) if prev_seen: msg += '; Time since last update: {}'.format(last_seen - prev_seen) _LOGGER.debug(msg) if (self._max_gps_accuracy is not None and gps_accuracy > self._max_gps_accuracy): _LOGGER.info('{}: Ignoring update because expected GPS ' 'accuracy {} is not met: {}'.format( dev_id, gps_accuracy, self._max_gps_accuracy)) return place_name = loc.get('name') or None # Does user want location name to be shown as state? if SHOW_PLACES in self._show_as_state: loc_name = place_name # Make sure Home Place is always seen exactly as home, # which is the special device_tracker state for home. if loc_name and loc_name.lower() == self._home_place: loc_name = STATE_HOME else: loc_name = None # If a place name is given, then address will just be a copy of # it, so don't bother with address. Otherwise, piece address # lines together, depending on which are present. if place_name: address = None else: address1 = loc.get('address1') or None address2 = loc.get('address2') or None if address1 and address2: address = ', '.join([address1, address2]) else: address = address1 or address2 raw_speed = loc.get('speed') try: speed = float(raw_speed) * SPEED_FACTOR_MPH if self._hass.config.units.is_metric: speed = convert(speed, LENGTH_MILES, LENGTH_KILOMETERS) speed = max(0, round(speed)) except (TypeError, ValueError): speed = STATE_UNKNOWN driving = bool_attr_from_int(loc.get('isDriving')) if (driving in (STATE_UNKNOWN, False) and self._driving_speed is not None and speed != STATE_UNKNOWN): driving = speed >= self._driving_speed moving = bool_attr_from_int(loc.get('inTransit')) if self._time_as in [TZ_DEVICE_UTC, TZ_DEVICE_LOCAL]: # timezone_at will return a string or None. tzname = self._tf.timezone_at(lng=lon, lat=lat) # get_time_zone will return a tzinfo or None. tz = dt_util.get_time_zone(tzname) attrs = {ATTR_TIME_ZONE: tzname or STATE_UNKNOWN} else: tz = None attrs = {} attrs.update({ ATTR_ADDRESS: address, ATTR_AT_LOC_SINCE: self._dt_attr_from_ts(loc.get('since'), tz), ATTR_BATTERY_CHARGING: bool_attr_from_int(loc.get('charge')), ATTR_DRIVING: driving, ATTR_LAST_SEEN: self._dt_attr_from_utc(last_seen, tz), ATTR_MOVING: moving, ATTR_RAW_SPEED: raw_speed, ATTR_SPEED: speed, ATTR_WIFI_ON: bool_attr_from_int(loc.get('wifiState')), }) # If we don't have a location name yet and user wants driving or moving # to be shown as state, and current location is not in a HA zone, # then update location name accordingly. if not loc_name and not active_zone(self._hass, lat, lon, gps_accuracy): if SHOW_DRIVING in self._show_as_state and driving is True: loc_name = SHOW_DRIVING.capitalize() elif SHOW_MOVING in self._show_as_state and moving is True: loc_name = SHOW_MOVING.capitalize() try: battery = int(float(loc.get('battery'))) except (TypeError, ValueError): battery = None self._see(dev_id=dev_id, location_name=loc_name, gps=(lat, lon), gps_accuracy=gps_accuracy, battery=battery, attributes=attrs, picture=m.get('avatar'))