* Fix #21821 * datetime fix * local time to utc conversion fix * Test cases update * date import removed * Update tod.py
This commit is contained in:
parent
650658ea01
commit
0a6ba14444
2 changed files with 43 additions and 36 deletions
|
@ -119,6 +119,17 @@ class TodSensor(BinarySensorDevice):
|
||||||
self.hass.config.time_zone).isoformat(),
|
self.hass.config.time_zone).isoformat(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def _naive_time_to_utc_datetime(self, naive_time):
|
||||||
|
"""Convert naive time from config to utc_datetime with current day."""
|
||||||
|
# get the current local date from utc time
|
||||||
|
current_local_date = self.current_datetime.astimezone(
|
||||||
|
self.hass.config.time_zone).date()
|
||||||
|
# calcuate utc datetime corecponding to local time
|
||||||
|
utc_datetime = self.hass.config.time_zone.localize(
|
||||||
|
datetime.combine(
|
||||||
|
current_local_date, naive_time)).astimezone(tz=pytz.UTC)
|
||||||
|
return utc_datetime
|
||||||
|
|
||||||
def _calculate_initial_boudary_time(self):
|
def _calculate_initial_boudary_time(self):
|
||||||
"""Calculate internal absolute time boudaries."""
|
"""Calculate internal absolute time boudaries."""
|
||||||
nowutc = self.current_datetime
|
nowutc = self.current_datetime
|
||||||
|
@ -134,9 +145,7 @@ class TodSensor(BinarySensorDevice):
|
||||||
# datetime.combine(date, time, tzinfo) is not supported
|
# datetime.combine(date, time, tzinfo) is not supported
|
||||||
# in python 3.5. The self._after is provided
|
# in python 3.5. The self._after is provided
|
||||||
# with hass configured TZ not system wide
|
# with hass configured TZ not system wide
|
||||||
after_event_date = datetime.combine(
|
after_event_date = self._naive_time_to_utc_datetime(self._after)
|
||||||
nowutc, self._after.replace(
|
|
||||||
tzinfo=self.hass.config.time_zone)).astimezone(tz=pytz.UTC)
|
|
||||||
|
|
||||||
self._time_after = after_event_date
|
self._time_after = after_event_date
|
||||||
|
|
||||||
|
@ -154,9 +163,7 @@ class TodSensor(BinarySensorDevice):
|
||||||
self.hass, self._before, after_event_date)
|
self.hass, self._before, after_event_date)
|
||||||
else:
|
else:
|
||||||
# Convert local time provided to UTC today, see above
|
# Convert local time provided to UTC today, see above
|
||||||
before_event_date = datetime.combine(
|
before_event_date = self._naive_time_to_utc_datetime(self._before)
|
||||||
nowutc, self._before.replace(
|
|
||||||
tzinfo=self.hass.config.time_zone)).astimezone(tz=pytz.UTC)
|
|
||||||
|
|
||||||
# It is safe to add timedelta days=1 to UTC as there is no DST
|
# It is safe to add timedelta days=1 to UTC as there is no DST
|
||||||
if before_event_date < after_event_date + self._after_offset:
|
if before_event_date < after_event_date + self._after_offset:
|
||||||
|
@ -190,7 +197,6 @@ class TodSensor(BinarySensorDevice):
|
||||||
|
|
||||||
async def async_added_to_hass(self):
|
async def async_added_to_hass(self):
|
||||||
"""Call when entity about to be added to Home Assistant."""
|
"""Call when entity about to be added to Home Assistant."""
|
||||||
await super().async_added_to_hass()
|
|
||||||
self._calculate_initial_boudary_time()
|
self._calculate_initial_boudary_time()
|
||||||
self._calculate_next_update()
|
self._calculate_next_update()
|
||||||
self._point_in_time_listener(dt_util.now())
|
self._point_in_time_listener(dt_util.now())
|
||||||
|
|
|
@ -110,8 +110,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_midnight_turnover_after_midnight_inside_period(self):
|
def test_midnight_turnover_after_midnight_inside_period(self):
|
||||||
"""Test midnight turnover setting before midnight inside period ."""
|
"""Test midnight turnover setting before midnight inside period ."""
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 10, 21, 00, 0, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 10, 21, 0, 0)).astimezone(pytz.UTC)
|
||||||
config = {
|
config = {
|
||||||
'binary_sensor': [
|
'binary_sensor': [
|
||||||
{
|
{
|
||||||
|
@ -143,8 +143,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_midnight_turnover_before_midnight_outside_period(self):
|
def test_midnight_turnover_before_midnight_outside_period(self):
|
||||||
"""Test midnight turnover setting before midnight outside period."""
|
"""Test midnight turnover setting before midnight outside period."""
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 10, 20, 30, 0, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 10, 20, 30, 0)).astimezone(pytz.UTC)
|
||||||
config = {
|
config = {
|
||||||
'binary_sensor': [
|
'binary_sensor': [
|
||||||
{
|
{
|
||||||
|
@ -165,8 +165,9 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_midnight_turnover_after_midnight_outside_period(self):
|
def test_midnight_turnover_after_midnight_outside_period(self):
|
||||||
"""Test midnight turnover setting before midnight inside period ."""
|
"""Test midnight turnover setting before midnight inside period ."""
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 10, 20, 0, 0, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 10, 20, 0, 0)).astimezone(pytz.UTC)
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
'binary_sensor': [
|
'binary_sensor': [
|
||||||
{
|
{
|
||||||
|
@ -185,8 +186,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
state = self.hass.states.get('binary_sensor.night')
|
state = self.hass.states.get('binary_sensor.night')
|
||||||
assert state.state == STATE_OFF
|
assert state.state == STATE_OFF
|
||||||
|
|
||||||
switchover_time = datetime(
|
switchover_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 11, 4, 59, 0, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 11, 4, 59, 0)).astimezone(pytz.UTC)
|
||||||
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
with patch('homeassistant.components.binary_sensor.tod.dt_util.utcnow',
|
||||||
return_value=switchover_time):
|
return_value=switchover_time):
|
||||||
|
|
||||||
|
@ -210,8 +211,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_from_sunrise_to_sunset(self):
|
def test_from_sunrise_to_sunset(self):
|
||||||
"""Test period from sunrise to sunset."""
|
"""Test period from sunrise to sunset."""
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 12, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 12)).astimezone(pytz.UTC)
|
||||||
sunrise = dt_util.as_local(get_astral_event_date(
|
sunrise = dt_util.as_local(get_astral_event_date(
|
||||||
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
||||||
sunset = dt_util.as_local(get_astral_event_date(
|
sunset = dt_util.as_local(get_astral_event_date(
|
||||||
|
@ -299,8 +300,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_from_sunset_to_sunrise(self):
|
def test_from_sunset_to_sunrise(self):
|
||||||
"""Test period from sunset to sunrise."""
|
"""Test period from sunset to sunrise."""
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 12, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 12)).astimezone(pytz.UTC)
|
||||||
sunset = dt_util.as_local(get_astral_event_date(
|
sunset = dt_util.as_local(get_astral_event_date(
|
||||||
self.hass, 'sunset', test_time))
|
self.hass, 'sunset', test_time))
|
||||||
sunrise = dt_util.as_local(get_astral_event_next(
|
sunrise = dt_util.as_local(get_astral_event_next(
|
||||||
|
@ -385,14 +386,14 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_offset(self):
|
def test_offset(self):
|
||||||
"""Test offset."""
|
"""Test offset."""
|
||||||
after = datetime(
|
after = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 10, 18, 0, 0,
|
datetime(2019, 1, 10, 18, 0, 0)).astimezone(pytz.UTC) + \
|
||||||
tzinfo=self.hass.config.time_zone) + \
|
|
||||||
timedelta(hours=1, minutes=34)
|
timedelta(hours=1, minutes=34)
|
||||||
before = datetime(
|
|
||||||
2019, 1, 10, 22, 0, 0,
|
before = self.hass.config.time_zone.localize(
|
||||||
tzinfo=self.hass.config.time_zone) + \
|
datetime(2019, 1, 10, 22, 0, 0)).astimezone(pytz.UTC) + \
|
||||||
timedelta(hours=1, minutes=45)
|
timedelta(hours=1, minutes=45)
|
||||||
|
|
||||||
entity_id = 'binary_sensor.evening'
|
entity_id = 'binary_sensor.evening'
|
||||||
config = {
|
config = {
|
||||||
'binary_sensor': [
|
'binary_sensor': [
|
||||||
|
@ -457,9 +458,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_offset_overnight(self):
|
def test_offset_overnight(self):
|
||||||
"""Test offset overnight."""
|
"""Test offset overnight."""
|
||||||
after = datetime(
|
after = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 10, 18, 0, 0,
|
datetime(2019, 1, 10, 18, 0, 0)).astimezone(pytz.UTC) + \
|
||||||
tzinfo=self.hass.config.time_zone) + \
|
|
||||||
timedelta(hours=1, minutes=34)
|
timedelta(hours=1, minutes=34)
|
||||||
entity_id = 'binary_sensor.evening'
|
entity_id = 'binary_sensor.evening'
|
||||||
config = {
|
config = {
|
||||||
|
@ -498,7 +498,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
self.hass.config.latitude = 69.6
|
self.hass.config.latitude = 69.6
|
||||||
self.hass.config.longitude = 18.8
|
self.hass.config.longitude = 18.8
|
||||||
|
|
||||||
test_time = datetime(2010, 1, 1, tzinfo=self.hass.config.time_zone)
|
test_time = self.hass.config.time_zone.localize(
|
||||||
|
datetime(2010, 1, 1)).astimezone(pytz.UTC)
|
||||||
sunrise = dt_util.as_local(get_astral_event_next(
|
sunrise = dt_util.as_local(get_astral_event_next(
|
||||||
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
||||||
sunset = dt_util.as_local(get_astral_event_next(
|
sunset = dt_util.as_local(get_astral_event_next(
|
||||||
|
@ -600,13 +601,13 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
self.hass.config.latitude = 69.6
|
self.hass.config.latitude = 69.6
|
||||||
self.hass.config.longitude = 18.8
|
self.hass.config.longitude = 18.8
|
||||||
|
|
||||||
test_time = datetime(2010, 6, 1, tzinfo=self.hass.config.time_zone)
|
test_time = self.hass.config.time_zone.localize(
|
||||||
|
datetime(2010, 6, 1)).astimezone(pytz.UTC)
|
||||||
|
|
||||||
sunrise = dt_util.as_local(get_astral_event_next(
|
sunrise = dt_util.as_local(get_astral_event_next(
|
||||||
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
self.hass, 'sunrise', dt_util.as_utc(test_time)))
|
||||||
sunset = dt_util.as_local(get_astral_event_next(
|
sunset = dt_util.as_local(get_astral_event_next(
|
||||||
self.hass, 'sunset', dt_util.as_utc(test_time)))
|
self.hass, 'sunset', dt_util.as_utc(test_time)))
|
||||||
print(sunrise)
|
|
||||||
print(sunset)
|
|
||||||
config = {
|
config = {
|
||||||
'binary_sensor': [
|
'binary_sensor': [
|
||||||
{
|
{
|
||||||
|
@ -701,8 +702,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
|
|
||||||
def test_sun_offset(self):
|
def test_sun_offset(self):
|
||||||
"""Test sun event with offset."""
|
"""Test sun event with offset."""
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 1, 12, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 1, 12)).astimezone(pytz.UTC)
|
||||||
sunrise = dt_util.as_local(get_astral_event_date(
|
sunrise = dt_util.as_local(get_astral_event_date(
|
||||||
self.hass, 'sunrise', dt_util.as_utc(test_time)) +
|
self.hass, 'sunrise', dt_util.as_utc(test_time)) +
|
||||||
timedelta(hours=-1, minutes=-30))
|
timedelta(hours=-1, minutes=-30))
|
||||||
|
@ -810,8 +811,8 @@ class TestBinarySensorTod(unittest.TestCase):
|
||||||
def test_dst(self):
|
def test_dst(self):
|
||||||
"""Test sun event with offset."""
|
"""Test sun event with offset."""
|
||||||
self.hass.config.time_zone = pytz.timezone('CET')
|
self.hass.config.time_zone = pytz.timezone('CET')
|
||||||
test_time = datetime(
|
test_time = self.hass.config.time_zone.localize(
|
||||||
2019, 3, 30, 3, 0, 0, tzinfo=self.hass.config.time_zone)
|
datetime(2019, 3, 30, 3, 0, 0)).astimezone(pytz.UTC)
|
||||||
config = {
|
config = {
|
||||||
'binary_sensor': [
|
'binary_sensor': [
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue