Use standardised datetime format

This commit is contained in:
Paulus Schoutsen 2016-04-16 00:55:35 -07:00
parent e7520ef401
commit 68d92c3196
29 changed files with 154 additions and 162 deletions

View file

@ -24,7 +24,7 @@ _LOGGER = logging.getLogger(__name__)
def trigger(hass, config, action):
"""Listen for state changes based on configuration."""
if CONF_AFTER in config:
after = dt_util.parse_time_str(config[CONF_AFTER])
after = dt_util.parse_time(config[CONF_AFTER])
if after is None:
_error_time(config[CONF_AFTER], CONF_AFTER)
return False
@ -62,13 +62,13 @@ def if_action(hass, config):
return None
if before is not None:
before = dt_util.parse_time_str(before)
before = dt_util.parse_time(before)
if before is None:
_error_time(before, CONF_BEFORE)
return None
if after is not None:
after = dt_util.parse_time_str(after)
after = dt_util.parse_time(after)
if after is None:
_error_time(after, CONF_AFTER)
return None

View file

@ -49,8 +49,7 @@ class VeraBinarySensor(VeraDevice, BinarySensorDevice):
last_tripped = self.vera_device.last_trip
if last_tripped is not None:
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
utc_time)
attr[ATTR_LAST_TRIP_TIME] = utc_time.isoformat()
else:
attr[ATTR_LAST_TRIP_TIME] = None
tripped = self.vera_device.is_tripped

View file

@ -182,7 +182,7 @@ def _api_history_period(handler, path_match, data):
one_day = timedelta(seconds=86400)
if date_str:
start_date = dt_util.date_str_to_date(date_str)
start_date = dt_util.parse_date(date_str)
if start_date is None:
handler.write_json_message("Error parsing JSON", HTTP_BAD_REQUEST)

View file

@ -72,8 +72,7 @@ class VeraLight(VeraDevice, Light):
last_tripped = self.vera_device.last_trip
if last_tripped is not None:
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
utc_time)
attr[ATTR_LAST_TRIP_TIME] = utc_time.isoformat()
else:
attr[ATTR_LAST_TRIP_TIME] = None
tripped = self.vera_device.is_tripped

View file

@ -87,7 +87,7 @@ def _handle_get_logbook(handler, path_match, data):
date_str = path_match.group('date')
if date_str:
start_date = dt_util.date_str_to_date(date_str)
start_date = dt_util.parse_date(date_str)
if start_date is None:
handler.write_json_message("Error parsing JSON", HTTP_BAD_REQUEST)
@ -122,7 +122,7 @@ class Entry(object):
def as_dict(self):
"""Convert entry to a dict to be used within JSON."""
return {
'when': dt_util.datetime_to_str(self.when),
'when': self.when,
'name': self.name,
'message': self.message,
'domain': self.domain,

View file

@ -44,12 +44,12 @@ class FileNotificationService(BaseNotificationService):
if os.stat(self.filepath).st_size == 0:
title = '{} notifications (Log started: {})\n{}\n'.format(
kwargs.get(ATTR_TITLE),
dt_util.strip_microseconds(dt_util.utcnow()),
dt_util.utcnow().isoformat(),
'-' * 80)
file.write(title)
if self.add_timestamp == 1:
text = '{} {}\n'.format(dt_util.utcnow(), message)
text = '{} {}\n'.format(dt_util.utcnow().isoformat(), message)
file.write(text)
else:
text = '{}\n'.format(message)

View file

@ -478,7 +478,7 @@ class Recorder(threading.Thread):
def _adapt_datetime(datetimestamp):
"""Turn a datetime into an integer for in the DB."""
return dt_util.as_utc(datetimestamp.replace(microsecond=0)).timestamp()
return dt_util.as_utc(datetimestamp).timestamp()
def _verify_instance():

View file

@ -23,6 +23,8 @@ ATTR_TARGET = 'Destination'
ATTR_REMAINING_TIME = 'Remaining time'
ICON = 'mdi:bus'
TIME_STR_FORMAT = "%H:%M"
# Return cached results if last scan was less then this time ago.
MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=60)
@ -126,10 +128,10 @@ class PublicTransportData(object):
try:
self.times = [
dt_util.datetime_to_time_str(
dt_util.as_local(dt_util.utc_from_timestamp(
item['from']['departureTimestamp']))
)
dt_util.as_local(
dt_util.utc_from_timestamp(
item['from']['departureTimestamp'])).strftime(
TIME_STR_FORMAT)
for item in connections
]
self.times.append(

View file

@ -131,9 +131,9 @@ class SystemMonitorSensor(Entity):
elif self.type == 'ipv6_address':
self._state = psutil.net_if_addrs()[self.argument][1][1]
elif self.type == 'last_boot':
self._state = dt_util.datetime_to_date_str(
dt_util.as_local(
dt_util.utc_from_timestamp(psutil.boot_time())))
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())

View file

@ -19,6 +19,8 @@ OPTION_TYPES = {
'time_utc': 'Time (UTC)',
}
TIME_STR_FORMAT = "%H:%M"
def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the Time and Date sensor."""
@ -70,9 +72,9 @@ class TimeDateSensor(Entity):
def update(self):
"""Get 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))
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 the beat (Swatch Internet Time) time without date.
hours, minutes, seconds = time_date.strftime('%H:%M:%S').split(':')

View file

@ -65,8 +65,7 @@ class VeraSensor(VeraDevice, Entity):
last_tripped = self.vera_device.last_trip
if last_tripped is not None:
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
utc_time)
attr[ATTR_LAST_TRIP_TIME] = utc_time.isoformat()
else:
attr[ATTR_LAST_TRIP_TIME] = None
tripped = self.vera_device.is_tripped

View file

@ -12,6 +12,7 @@ from homeassistant.helpers.entity import Entity
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "Worldclock Sensor"
ICON = 'mdi:clock'
TIME_STR_FORMAT = "%H:%M"
def setup_platform(hass, config, add_devices, discovery_info=None):
@ -59,5 +60,5 @@ class WorldClockSensor(Entity):
def update(self):
"""Get the time and updates the states."""
self._state = dt_util.datetime_to_time_str(
dt_util.now(time_zone=self._time_zone))
self._state = dt_util.now(time_zone=self._time_zone).strftime(
TIME_STR_FORMAT)

View file

@ -138,10 +138,8 @@ class YrSensor(Entity):
# Find sensor
for time_entry in self._weather.data['product']['time']:
valid_from = dt_util.str_to_datetime(
time_entry['@from'], "%Y-%m-%dT%H:%M:%SZ")
valid_to = dt_util.str_to_datetime(
time_entry['@to'], "%Y-%m-%dT%H:%M:%SZ")
valid_from = dt_util.parse_datetime(time_entry['@from'])
valid_to = dt_util.parse_datetime(time_entry['@to'])
loc_data = time_entry['location']
@ -204,5 +202,4 @@ class YrData(object):
model = self.data['meta']['model']
if '@nextrun' not in model:
model = model[0]
self._nextrun = dt_util.str_to_datetime(model['@nextrun'],
"%Y-%m-%dT%H:%M:%SZ")
self._nextrun = dt_util.parse_datetime(model['@nextrun'])

View file

@ -50,7 +50,7 @@ def next_setting_utc(hass, entity_id=None):
state = hass.states.get(ENTITY_ID)
try:
return dt_util.str_to_datetime(
return dt_util.parse_datetime(
state.attributes[STATE_ATTR_NEXT_SETTING])
except (AttributeError, KeyError):
# AttributeError if state is None
@ -72,8 +72,7 @@ def next_rising_utc(hass, entity_id=None):
state = hass.states.get(ENTITY_ID)
try:
return dt_util.str_to_datetime(
state.attributes[STATE_ATTR_NEXT_RISING])
return dt_util.parse_datetime(state.attributes[STATE_ATTR_NEXT_RISING])
except (AttributeError, KeyError):
# AttributeError if state is None
# KeyError if STATE_ATTR_NEXT_RISING does not exist
@ -150,10 +149,8 @@ class Sun(Entity):
def state_attributes(self):
"""Return the state attributes of the sun."""
return {
STATE_ATTR_NEXT_RISING:
dt_util.datetime_to_str(self.next_rising),
STATE_ATTR_NEXT_SETTING:
dt_util.datetime_to_str(self.next_setting),
STATE_ATTR_NEXT_RISING: self.next_rising.isoformat(),
STATE_ATTR_NEXT_SETTING: self.next_setting.isoformat(),
STATE_ATTR_ELEVATION: round(self.solar_elevation, 2)
}

View file

@ -50,8 +50,7 @@ class VeraSwitch(VeraDevice, SwitchDevice):
last_tripped = self.vera_device.last_trip
if last_tripped is not None:
utc_time = dt_util.utc_from_timestamp(int(last_tripped))
attr[ATTR_LAST_TRIP_TIME] = dt_util.datetime_to_str(
utc_time)
attr[ATTR_LAST_TRIP_TIME] = utc_time.isoformat()
else:
attr[ATTR_LAST_TRIP_TIME] = None
tripped = self.vera_device.is_tripped

View file

@ -156,8 +156,7 @@ class Event(object):
self.event_type = event_type
self.data = data or {}
self.origin = origin
self.time_fired = dt_util.strip_microseconds(
time_fired or dt_util.utcnow())
self.time_fired = time_fired or dt_util.utcnow()
def as_dict(self):
"""Create a dict representation of this Event."""
@ -165,7 +164,7 @@ class Event(object):
'event_type': self.event_type,
'data': dict(self.data),
'origin': str(self.origin),
'time_fired': dt_util.datetime_to_str(self.time_fired),
'time_fired': self.time_fired,
}
def __repr__(self):
@ -310,15 +309,9 @@ class State(object):
self.entity_id = entity_id.lower()
self.state = str(state)
self.attributes = MappingProxyType(attributes or {})
self.last_updated = dt_util.strip_microseconds(
last_updated or dt_util.utcnow())
self.last_updated = last_updated or dt_util.utcnow()
# Strip microsecond from last_changed else we cannot guarantee
# state == State.from_dict(state.as_dict())
# This behavior occurs because to_dict uses datetime_to_str
# which does not preserve microseconds
self.last_changed = dt_util.strip_microseconds(
last_changed or self.last_updated)
self.last_changed = last_changed or self.last_updated
@property
def domain(self):
@ -346,8 +339,8 @@ class State(object):
return {'entity_id': self.entity_id,
'state': self.state,
'attributes': dict(self.attributes),
'last_changed': dt_util.datetime_to_str(self.last_changed),
'last_updated': dt_util.datetime_to_str(self.last_updated)}
'last_changed': self.last_changed,
'last_updated': self.last_updated}
@classmethod
def from_dict(cls, json_dict):
@ -361,13 +354,13 @@ class State(object):
last_changed = json_dict.get('last_changed')
if last_changed:
last_changed = dt_util.str_to_datetime(last_changed)
if isinstance(last_changed, str):
last_changed = dt_util.parse_datetime(last_changed)
last_updated = json_dict.get('last_updated')
if last_updated:
last_updated = dt_util.str_to_datetime(last_updated)
if isinstance(last_updated, str):
last_updated = dt_util.parse_datetime(last_updated)
return cls(json_dict['entity_id'], json_dict['state'],
json_dict.get('attributes'), last_changed, last_updated)
@ -386,7 +379,7 @@ class State(object):
return "<state {}={}{} @ {}>".format(
self.entity_id, self.state, attr,
dt_util.datetime_to_local_str(self.last_changed))
dt_util.as_local(self.last_changed).isoformat())
class StateMachine(object):
@ -819,6 +812,6 @@ def create_worker_pool(worker_count=None):
for start, job in current_jobs:
_LOGGER.warning("WorkerPool:Current job from %s: %s",
dt_util.datetime_to_local_str(start), job)
dt_util.as_local(start).isoformat(), job)
return util.ThreadPool(job_handler, worker_count, busy_callback)

View file

@ -92,9 +92,8 @@ class TrackStates(object):
def get_changed_since(states, utc_point_in_time):
"""Return list of states that have been changed since utc_point_in_time."""
point_in_time = dt_util.strip_microseconds(utc_point_in_time)
return [state for state in states if state.last_updated >= point_in_time]
return [state for state in states
if state.last_updated >= utc_point_in_time]
def reproduce_state(hass, states, blocking=False):

View file

@ -7,6 +7,7 @@ HomeAssistantError will be raised.
For more details about the Python API, please refer to the documentation at
https://home-assistant.io/developers/python_api/
"""
from datetime import datetime
import enum
import json
import logging
@ -277,7 +278,9 @@ class JSONEncoder(json.JSONEncoder):
Hand other objects to the original method.
"""
if hasattr(obj, 'as_dict'):
if isinstance(obj, datetime):
return obj.isoformat()
elif hasattr(obj, 'as_dict'):
return obj.as_dict()
try:

View file

@ -12,7 +12,7 @@ import string
from functools import wraps
from types import MappingProxyType
from .dt import datetime_to_local_str, utcnow
from .dt import as_local, utcnow
RE_SANITIZE_FILENAME = re.compile(r'(~|\.\.|/|\\)')
RE_SANITIZE_PATH = re.compile(r'(~|\.(\.)+)')
@ -43,7 +43,7 @@ def repr_helper(inp):
repr_helper(key)+"="+repr_helper(item) for key, item
in inp.items())
elif isinstance(inp, datetime):
return datetime_to_local_str(inp)
return as_local(inp).isoformat()
else:
return str(inp)

View file

@ -1,14 +1,24 @@
"""Provides helper methods to handle the time in HA."""
import datetime as dt
import re
import pytz
DATETIME_STR_FORMAT = "%H:%M:%S %d-%m-%Y"
DATE_STR_FORMAT = "%Y-%m-%d"
TIME_STR_FORMAT = "%H:%M"
UTC = DEFAULT_TIME_ZONE = pytz.utc
# Copyright (c) Django Software Foundation and individual contributors.
# All rights reserved.
# https://github.com/django/django/blob/master/LICENSE
DATETIME_RE = re.compile(
r'(?P<year>\d{4})-(?P<month>\d{1,2})-(?P<day>\d{1,2})'
r'[T ](?P<hour>\d{1,2}):(?P<minute>\d{1,2})'
r'(?::(?P<second>\d{1,2})(?:\.(?P<microsecond>\d{1,6})\d{0,6})?)?'
r'(?P<tzinfo>Z|[+-]\d{2}(?::?\d{2})?)?$'
)
def set_default_time_zone(time_zone):
"""Set a default time zone to be used when none is specified."""
global DEFAULT_TIME_ZONE # pylint: disable=global-statement
@ -75,48 +85,39 @@ def start_of_local_day(dt_or_d=None):
tzinfo=DEFAULT_TIME_ZONE)
def datetime_to_local_str(dattim):
"""Convert datetime to specified time_zone and returns a string."""
return datetime_to_str(as_local(dattim))
# Copyright (c) Django Software Foundation and individual contributors.
# All rights reserved.
# https://github.com/django/django/blob/master/LICENSE
def parse_datetime(dt_str):
"""Parse a string and return a datetime.datetime.
def datetime_to_str(dattim):
"""Convert datetime to a string format.
@rtype : str
This function supports time zone offsets. When the input contains one,
the output uses a timezone with a fixed offset from UTC.
Raises ValueError if the input is well formatted but not a valid datetime.
Returns None if the input isn't well formatted.
"""
return dattim.strftime(DATETIME_STR_FORMAT)
def datetime_to_time_str(dattim):
"""Convert datetime to a string containing only the time.
@rtype : str
"""
return dattim.strftime(TIME_STR_FORMAT)
def datetime_to_date_str(dattim):
"""Convert datetime to a string containing only the date.
@rtype : str
"""
return dattim.strftime(DATE_STR_FORMAT)
def str_to_datetime(dt_str, dt_format=DATETIME_STR_FORMAT):
"""Convert a string to a UTC datetime object.
@rtype: datetime
"""
try:
return dt.datetime.strptime(
dt_str, dt_format).replace(tzinfo=pytz.utc)
except ValueError: # If dt_str did not match our format
match = DATETIME_RE.match(dt_str)
if not match:
return None
kws = match.groupdict()
if kws['microsecond']:
kws['microsecond'] = kws['microsecond'].ljust(6, '0')
tzinfo = kws.pop('tzinfo')
if tzinfo == 'Z':
tzinfo = UTC
elif tzinfo is not None:
offset_mins = int(tzinfo[-2:]) if len(tzinfo) > 3 else 0
offset_hours = int(tzinfo[1:3])
offset = dt.timedelta(hours=offset_hours, minutes=offset_mins)
if tzinfo[0] == '-':
offset = -offset
tzinfo = dt.timezone(offset)
kws = {k: int(v) for k, v in kws.items() if v is not None}
kws['tzinfo'] = tzinfo
return dt.datetime(**kws)
def date_str_to_date(dt_str):
def parse_date(dt_str):
"""Convert a date string to a date object."""
try:
return dt.datetime.strptime(dt_str, DATE_STR_FORMAT).date()
@ -124,12 +125,7 @@ def date_str_to_date(dt_str):
return None
def strip_microseconds(dattim):
"""Return a copy of dattime object but with microsecond set to 0."""
return dattim.replace(microsecond=0)
def parse_time_str(time_str):
def parse_time(time_str):
"""Parse a time string (00:20:00) into Time object.
Return None if invalid.

View file

@ -34,7 +34,7 @@ class TestAutomationSun(unittest.TestCase):
def test_sunset_trigger(self):
"""Test the sunset trigger."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_SETTING: '02:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T02:00:00Z',
})
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
@ -61,7 +61,7 @@ class TestAutomationSun(unittest.TestCase):
def test_sunrise_trigger(self):
"""Test the sunrise trigger."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
})
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
@ -88,7 +88,7 @@ class TestAutomationSun(unittest.TestCase):
def test_sunset_trigger_with_offset(self):
"""Test the sunset trigger with offset."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_SETTING: '02:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T02:00:00Z',
})
now = datetime(2015, 9, 15, 23, tzinfo=dt_util.UTC)
@ -116,7 +116,7 @@ class TestAutomationSun(unittest.TestCase):
def test_sunrise_trigger_with_offset(self):
"""Test the runrise trigger with offset."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
})
now = datetime(2015, 9, 13, 23, tzinfo=dt_util.UTC)
@ -144,7 +144,7 @@ class TestAutomationSun(unittest.TestCase):
def test_if_action_before(self):
"""Test if action was before."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
})
_setup_component(self.hass, automation.DOMAIN, {
@ -180,7 +180,7 @@ class TestAutomationSun(unittest.TestCase):
def test_if_action_after(self):
"""Test if action was after."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
})
_setup_component(self.hass, automation.DOMAIN, {
@ -216,7 +216,7 @@ class TestAutomationSun(unittest.TestCase):
def test_if_action_before_with_offset(self):
"""Test if action was before offset."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
})
_setup_component(self.hass, automation.DOMAIN, {
@ -253,7 +253,7 @@ class TestAutomationSun(unittest.TestCase):
def test_if_action_after_with_offset(self):
"""Test if action was after offset."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '14:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T14:00:00Z',
})
_setup_component(self.hass, automation.DOMAIN, {
@ -290,8 +290,8 @@ class TestAutomationSun(unittest.TestCase):
def test_if_action_before_and_after_during(self):
"""Test if action was before and after during."""
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_RISING: '10:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_SETTING: '15:00:00 16-09-2015',
sun.STATE_ATTR_NEXT_RISING: '2015-09-16T10:00:00Z',
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T15:00:00Z',
})
_setup_component(self.hass, automation.DOMAIN, {
@ -337,7 +337,7 @@ class TestAutomationSun(unittest.TestCase):
import pytz
self.hass.states.set(sun.ENTITY_ID, sun.STATE_ABOVE_HORIZON, {
sun.STATE_ATTR_NEXT_SETTING: '17:30:00 16-09-2015',
sun.STATE_ATTR_NEXT_SETTING: '2015-09-16T17:30:00Z',
})
_setup_component(self.hass, automation.DOMAIN, {

View file

@ -2,6 +2,7 @@
import os
import unittest
import tempfile
from unittest.mock import patch
import homeassistant.components.notify as notify
from homeassistant.components.notify import (
@ -31,8 +32,11 @@ class TestNotifyFile(unittest.TestCase):
}
}))
def test_notify_file(self):
@patch('homeassistant.util.dt.utcnow')
def test_notify_file(self, mock_utcnow):
"""Test the notify file output."""
mock_utcnow.return_value = dt_util.as_utc(dt_util.now())
with tempfile.TemporaryDirectory() as tempdirname:
filename = os.path.join(tempdirname, 'notify.txt')
message = 'one, two, testing, testing'
@ -46,7 +50,7 @@ class TestNotifyFile(unittest.TestCase):
}))
title = '{} notifications (Log started: {})\n{}\n'.format(
ATTR_TITLE_DEFAULT,
dt_util.strip_microseconds(dt_util.utcnow()),
dt_util.utcnow().isoformat(),
'-' * 80)
self.hass.services.call('notify', 'test', {'message': message},

View file

@ -68,7 +68,7 @@ class TestComponentHistory(unittest.TestCase):
"""Test humanify filter too frequent sensor values."""
entity_id = 'sensor.bla'
pointA = dt_util.strip_microseconds(dt_util.utcnow().replace(minute=2))
pointA = dt_util.utcnow().replace(minute=2)
pointB = pointA.replace(minute=5)
pointC = pointA + timedelta(minutes=logbook.GROUP_BY_MINUTES)

View file

@ -66,13 +66,13 @@ class TestMqttEventStream(unittest.TestCase):
mock_sub.assert_called_with(self.hass, sub_topic, ANY)
@patch('homeassistant.components.mqtt.publish')
@patch('homeassistant.core.dt_util.datetime_to_str')
def test_state_changed_event_sends_message(self, mock_datetime, mock_pub):
@patch('homeassistant.core.dt_util.utcnow')
def test_state_changed_event_sends_message(self, mock_utcnow, mock_pub):
""""Test the sending of a new message if event changed."""
now = '00:19:19 11-01-2016'
now = dt_util.as_utc(dt_util.now())
e_id = 'fake.entity'
pub_topic = 'bar'
mock_datetime.return_value = now
mock_utcnow.return_value = now
# Add the eventstream component for publishing events
self.assertTrue(self.add_eventstream(pub_topic=pub_topic))
@ -97,11 +97,11 @@ class TestMqttEventStream(unittest.TestCase):
event = {}
event['event_type'] = EVENT_STATE_CHANGED
new_state = {
"last_updated": now,
"last_updated": now.isoformat(),
"state": "on",
"entity_id": e_id,
"attributes": {},
"last_changed": now
"last_changed": now.isoformat()
}
event['event_data'] = {"new_state": new_state, "entity_id": e_id}

View file

@ -63,4 +63,16 @@ class TestRecorder(unittest.TestCase):
db_events = recorder.query_events(
'SELECT * FROM events WHERE event_type = ?', (event_type, ))
self.assertEqual(events, db_events)
assert len(events) == 1
assert len(db_events) == 1
event = events[0]
db_event = db_events[0]
assert event.event_type == db_event.event_type
assert event.data == db_event.data
assert event.origin == db_event.origin
# Recorder uses SQLite and stores datetimes as integer unix timestamps
assert event.time_fired.replace(microsecond=0) == \
db_event.time_fired.replace(microsecond=0)

View file

@ -128,7 +128,7 @@ class TestEvent(unittest.TestCase):
'event_type': event_type,
'data': data,
'origin': 'LOCAL',
'time_fired': dt_util.datetime_to_str(now),
'time_fired': now,
}
self.assertEqual(expected, event.as_dict())
@ -225,13 +225,14 @@ class TestState(unittest.TestCase):
def test_repr(self):
"""Test state.repr."""
self.assertEqual("<state happy.happy=on @ 12:00:00 08-12-1984>",
self.assertEqual("<state happy.happy=on @ 1984-12-08T12:00:00+00:00>",
str(ha.State(
"happy.happy", "on",
last_changed=datetime(1984, 12, 8, 12, 0, 0))))
self.assertEqual(
"<state happy.happy=on; brightness=144 @ 12:00:00 08-12-1984>",
"<state happy.happy=on; brightness=144 @ "
"1984-12-08T12:00:00+00:00>",
str(ha.State("happy.happy", "on", {"brightness": 144},
datetime(1984, 12, 8, 12, 0, 0))))

View file

@ -7,6 +7,7 @@ import homeassistant.bootstrap as bootstrap
import homeassistant.remote as remote
import homeassistant.components.http as http
from homeassistant.const import HTTP_HEADER_HA_AUTH
import homeassistant.util.dt as dt_util
from tests.common import get_test_instance_port, get_test_home_assistant
@ -194,6 +195,9 @@ class TestRemoteMethods(unittest.TestCase):
# Default method raises TypeError if non HA object
self.assertRaises(TypeError, ha_json_enc.default, 1)
now = dt_util.utcnow()
self.assertEqual(now.isoformat(), ha_json_enc.default(now))
class TestRemoteClasses(unittest.TestCase):
"""Test the homeassistant.remote module."""

View file

@ -107,31 +107,16 @@ class TestDateUtil(unittest.TestCase):
datetime(1986, 7, 9, tzinfo=dt_util.UTC),
dt_util.utc_from_timestamp(521251200))
def test_datetime_to_str(self):
"""Test datetime_to_str."""
self.assertEqual(
"12:00:00 09-07-1986",
dt_util.datetime_to_str(datetime(1986, 7, 9, 12, 0, 0)))
def test_parse_datetime_converts_correctly(self):
"""Test parse_datetime converts strings."""
assert \
datetime(1986, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC) == \
dt_util.parse_datetime("1986-07-09T12:00:00Z")
def test_datetime_to_local_str(self):
"""Test datetime_to_local_str."""
self.assertEqual(
dt_util.datetime_to_str(dt_util.now()),
dt_util.datetime_to_local_str(dt_util.utcnow()))
utcnow = dt_util.utcnow()
def test_str_to_datetime_converts_correctly(self):
"""Test str_to_datetime converts strings."""
self.assertEqual(
datetime(1986, 7, 9, 12, 0, 0, tzinfo=dt_util.UTC),
dt_util.str_to_datetime("12:00:00 09-07-1986"))
assert utcnow == dt_util.parse_datetime(utcnow.isoformat())
def test_str_to_datetime_returns_none_for_incorrect_format(self):
"""Test str_to_datetime returns None if incorrect format."""
self.assertIsNone(dt_util.str_to_datetime("not a datetime string"))
def test_strip_microseconds(self):
"""Test the now method."""
test_time = datetime(2015, 1, 1, microsecond=5000)
self.assertNotEqual(0, test_time.microsecond)
self.assertEqual(0, dt_util.strip_microseconds(test_time).microsecond)
def test_parse_datetime_returns_none_for_incorrect_format(self):
"""Test parse_datetime returns None if incorrect format."""
self.assertIsNone(dt_util.parse_datetime("not a datetime string"))

View file

@ -39,7 +39,7 @@ class TestUtil(unittest.TestCase):
self.assertEqual("True", util.repr_helper(True))
self.assertEqual("test=1",
util.repr_helper({"test": 1}))
self.assertEqual("12:00:00 09-07-1986",
self.assertEqual("1986-07-09T12:00:00+00:00",
util.repr_helper(datetime(1986, 7, 9, 12, 0, 0)))
def test_convert(self):