diff --git a/homeassistant/__init__.py b/homeassistant/__init__.py index b93a8ee99be..d1cb17f22c6 100644 --- a/homeassistant/__init__.py +++ b/homeassistant/__init__.py @@ -22,7 +22,7 @@ from homeassistant.const import ( SERVICE_HOMEASSISTANT_STOP, EVENT_TIME_CHANGED, EVENT_STATE_CHANGED, EVENT_CALL_SERVICE, ATTR_NOW, ATTR_DOMAIN, ATTR_SERVICE, MATCH_ALL, EVENT_SERVICE_EXECUTED, ATTR_SERVICE_CALL_ID, EVENT_SERVICE_REGISTERED, - TEMP_CELCIUS, TEMP_FAHRENHEIT) + TEMP_CELCIUS, TEMP_FAHRENHEIT, ATTR_FRIENDLY_NAME) import homeassistant.util as util DOMAIN = "homeassistant" @@ -325,19 +325,23 @@ class EventOrigin(enum.Enum): class Event(object): """ Represents an event within the Bus. """ - __slots__ = ['event_type', 'data', 'origin'] + __slots__ = ['event_type', 'data', 'origin', 'time_fired'] - def __init__(self, event_type, data=None, origin=EventOrigin.local): + def __init__(self, event_type, data=None, origin=EventOrigin.local, + time_fired=None): self.event_type = event_type self.data = data or {} self.origin = origin + self.time_fired = util.strip_microseconds( + time_fired or dt.datetime.now()) def as_dict(self): """ Returns a dict representation of this Event. """ return { 'event_type': self.event_type, 'data': dict(self.data), - 'origin': str(self.origin) + 'origin': str(self.origin), + 'time_fired': util.datetime_to_str(self.time_fired), } def __repr__(self): @@ -482,6 +486,18 @@ class State(object): """ Returns domain of this state. """ return util.split_entity_id(self.entity_id)[0] + @property + def object_id(self): + """ Returns object_id of this state. """ + return util.split_entity_id(self.entity_id)[1] + + @property + def name(self): + """ Name to represent this state. """ + return ( + self.attributes.get(ATTR_FRIENDLY_NAME) or + self.object_id.replace('_', ' ')) + def copy(self): """ Creates a copy of itself. """ return State(self.entity_id, self.state, diff --git a/homeassistant/components/recorder.py b/homeassistant/components/recorder.py index 367af7d2d73..b71ed06203f 100644 --- a/homeassistant/components/recorder.py +++ b/homeassistant/components/recorder.py @@ -70,9 +70,10 @@ def row_to_state(row): def row_to_event(row): """ Convert a databse row to an event. """ try: - return Event(row[1], json.loads(row[2]), EventOrigin[row[3].lower()]) + return Event(row[1], json.loads(row[2]), EventOrigin[row[3].lower()], + datetime.fromtimestamp(row[5])) except ValueError: - # When json.oads fails + # When json.loads fails _LOGGER.exception("Error converting row to event: %s", row) return None @@ -225,13 +226,13 @@ class Recorder(threading.Thread): """ Save an event to the database. """ info = ( event.event_type, json.dumps(event.data, cls=JSONEncoder), - str(event.origin), datetime.now() + str(event.origin), datetime.now(), event.time_fired, ) self.query( "INSERT INTO events (" - "event_type, event_data, origin, created" - ") VALUES (?, ?, ?, ?)", info) + "event_type, event_data, origin, created, time_fired" + ") VALUES (?, ?, ?, ?, ?)", info) def query(self, sql_query, data=None, return_value=None): """ Query the database. """ @@ -328,6 +329,16 @@ class Recorder(threading.Thread): save_migration(1) + if migration_id < 2: + cur.execute(""" + ALTER TABLE events + ADD COLUMN time_fired integer + """) + + cur.execute('UPDATE events SET time_fired=created') + + save_migration(2) + def _close_connection(self): """ Close connection to the database. """ _LOGGER.info("Closing database")