コード例 #1
0
ファイル: test_location.py プロジェクト: lumavp/blumate
    def test_closest_with_no_states_with_location(self):
        """Setup the tests."""
        state = State('light.test', 'on')
        state2 = State('light.test', 'on', {
            ATTR_LATITUDE: 'invalid',
            ATTR_LONGITUDE: 123.45,
        })
        state3 = State('light.test', 'on', {
            ATTR_LONGITUDE: 123.45,
        })

        self.assertIsNone(
            location.closest(123.45, 123.45, [state, state2, state3]))
コード例 #2
0
ファイル: test_location.py プロジェクト: lumavp/blumate
    def test_closest_returns_closest(self):
        """Test ."""
        state = State('light.test', 'on', {
            ATTR_LATITUDE: 124.45,
            ATTR_LONGITUDE: 124.45,
        })
        state2 = State('light.test', 'on', {
            ATTR_LATITUDE: 125.45,
            ATTR_LONGITUDE: 125.45,
        })

        self.assertEqual(state,
                         location.closest(123.45, 123.45, [state, state2]))
コード例 #3
0
ファイル: blumate.py プロジェクト: lumavp/blumate
def _process_config(scene_config):
    """Process passed in config into a format to work with."""
    name = scene_config.get('name')

    states = {}
    c_entities = dict(scene_config.get(CONF_ENTITIES, {}))

    for entity_id in c_entities:
        if isinstance(c_entities[entity_id], dict):
            entity_attrs = c_entities[entity_id].copy()
            state = entity_attrs.pop('state', None)
            attributes = entity_attrs
        else:
            state = c_entities[entity_id]
            attributes = {}

        # YAML translates 'on' to a boolean
        # http://yaml.org/type/bool.html
        if isinstance(state, bool):
            state = STATE_ON if state else STATE_OFF
        else:
            state = str(state)

        states[entity_id.lower()] = State(entity_id, state, attributes)

    return SceneConfig(name, states)
コード例 #4
0
ファイル: test_location.py プロジェクト: lumavp/blumate
 def test_has_location_with_states_with_valid_location(self):
     """Setup the tests."""
     state = State('hello.world', 'invalid', {
         ATTR_LATITUDE: 123.12,
         ATTR_LONGITUDE: 123.12
     })
     self.assertTrue(location.has_location(state))
コード例 #5
0
ファイル: recorder.py プロジェクト: lumavp/blumate
def row_to_state(row):
    """Convert a database row to a state."""
    try:
        return State(row[1], row[2], json.loads(row[3]),
                     dt_util.utc_from_timestamp(row[4]),
                     dt_util.utc_from_timestamp(row[5]))
    except ValueError:
        # When json.loads fails
        _LOGGER.exception("Error converting row to state: %s", row)
        return None
コード例 #6
0
    def test_state_changed_event_sends_message(self, mock_utcnow, mock_pub):
        """"Test the sending of a new message if event changed."""
        now = dt_util.as_utc(dt_util.now())
        e_id = 'fake.entity'
        pub_topic = 'bar'
        mock_utcnow.return_value = now

        # Add the eventstream component for publishing events
        self.assertTrue(self.add_eventstream(pub_topic=pub_topic))
        self.hass.pool.block_till_done()

        # Reset the mock because it will have already gotten calls for the
        # mqtt_eventstream state change on initialization, etc.
        mock_pub.reset_mock()

        # Set a state of an entity
        mock_state_change_event(self.hass, State(e_id, 'on'))
        self.hass.pool.block_till_done()

        # The order of the JSON is indeterminate,
        # so first just check that publish was called
        mock_pub.assert_called_with(self.hass, pub_topic, ANY)
        self.assertTrue(mock_pub.called)

        # Get the actual call to publish and make sure it was the one
        # we were looking for
        msg = mock_pub.call_args[0][2]
        event = {}
        event['event_type'] = EVENT_STATE_CHANGED
        new_state = {
            "last_updated": now.isoformat(),
            "state": "on",
            "entity_id": e_id,
            "attributes": {},
            "last_changed": now.isoformat()
        }
        event['event_data'] = {"new_state": new_state, "entity_id": e_id}

        # Verify that the message received was that expected
        self.assertEqual(json.loads(msg), event)
コード例 #7
0
ファイル: mqtt_eventstream.py プロジェクト: lumavp/blumate
    def _event_receiver(topic, payload, qos):
        """Receive events published by and fire them on this hass instance."""
        event = json.loads(payload)
        event_type = event.get('event_type')
        event_data = event.get('event_data')

        # Special case handling for event STATE_CHANGED
        # We will try to convert state dicts back to State objects
        # Copied over from the _handle_api_post_events_event method
        # of the api component.
        if event_type == EVENT_STATE_CHANGED and event_data:
            for key in ('old_state', 'new_state'):
                state = State.from_dict(event_data.get(key))

                if state:
                    event_data[key] = state

        hass.bus.fire(
            event_type,
            event_data=event_data,
            origin=EventOrigin.remote
        )
コード例 #8
0
ファイル: logbook.py プロジェクト: lumavp/blumate
def humanify(events):
    """Generator that converts a list of events into Entry objects.

    Will try to group events if possible:
     - if 2+ sensor updates in GROUP_BY_MINUTES, show last
     - if home assistant stop and start happen in same minute call it restarted
    """
    # pylint: disable=too-many-branches
    # Group events in batches of GROUP_BY_MINUTES
    for _, g_events in groupby(
            events, lambda event: event.time_fired.minute // GROUP_BY_MINUTES):

        events_batch = list(g_events)

        # Keep track of last sensor states
        last_sensor_event = {}

        # Group HA start/stop events
        # Maps minute of event to 1: stop, 2: stop + start
        start_stop_events = {}

        # Process events
        for event in events_batch:
            if event.event_type == EVENT_STATE_CHANGED:
                entity_id = event.data.get('entity_id')

                if entity_id is None:
                    continue

                if entity_id.startswith('sensor.'):
                    last_sensor_event[entity_id] = event

            elif event.event_type == EVENT_BLUMATE_STOP:
                if event.time_fired.minute in start_stop_events:
                    continue

                start_stop_events[event.time_fired.minute] = 1

            elif event.event_type == EVENT_BLUMATE_START:
                if event.time_fired.minute not in start_stop_events:
                    continue

                start_stop_events[event.time_fired.minute] = 2

        # Yield entries
        for event in events_batch:
            if event.event_type == EVENT_STATE_CHANGED:

                # Do not report on new entities
                if 'old_state' not in event.data:
                    continue

                to_state = State.from_dict(event.data.get('new_state'))

                # If last_changed != last_updated only attributes have changed
                # we do not report on that yet. Also filter auto groups.
                if not to_state or \
                   to_state.last_changed != to_state.last_updated or \
                   to_state.domain == 'group' and \
                   to_state.attributes.get('auto', False):
                    continue

                domain = to_state.domain

                # Skip all but the last sensor state
                if domain == 'sensor' and \
                   event != last_sensor_event[to_state.entity_id]:
                    continue

                yield Entry(event.time_fired,
                            name=to_state.name,
                            message=_entry_message_from_state(
                                domain, to_state),
                            domain=domain,
                            entity_id=to_state.entity_id)

            elif event.event_type == EVENT_BLUMATE_START:
                if start_stop_events.get(event.time_fired.minute) == 2:
                    continue

                yield Entry(event.time_fired,
                            "Home Assistant",
                            "started",
                            domain=HA_DOMAIN)

            elif event.event_type == EVENT_BLUMATE_STOP:
                if start_stop_events.get(event.time_fired.minute) == 2:
                    action = "restarted"
                else:
                    action = "stopped"

                yield Entry(event.time_fired,
                            "Home Assistant",
                            action,
                            domain=HA_DOMAIN)

            elif event.event_type.lower() == EVENT_LOGBOOK_ENTRY:
                domain = event.data.get(ATTR_DOMAIN)
                entity_id = event.data.get(ATTR_ENTITY_ID)
                if domain is None and entity_id is not None:
                    try:
                        domain = split_entity_id(str(entity_id))[0]
                    except IndexError:
                        pass

                yield Entry(event.time_fired, event.data.get(ATTR_NAME),
                            event.data.get(ATTR_MESSAGE), domain, entity_id)
コード例 #9
0
ファイル: logbook.py プロジェクト: bdfoster/blumate
def humanify(events):
    """Generator that converts a list of events into Entry objects.

    Will try to group events if possible:
     - if 2+ sensor updates in GROUP_BY_MINUTES, show last
     - if home assistant stop and start happen in same minute call it restarted
    """
    # pylint: disable=too-many-branches
    # Group events in batches of GROUP_BY_MINUTES
    for _, g_events in groupby(
            events,
            lambda event: event.time_fired.minute // GROUP_BY_MINUTES):

        events_batch = list(g_events)

        # Keep track of last sensor states
        last_sensor_event = {}

        # Group HA start/stop events
        # Maps minute of event to 1: stop, 2: stop + start
        start_stop_events = {}

        # Process events
        for event in events_batch:
            if event.event_type == EVENT_STATE_CHANGED:
                entity_id = event.data.get('entity_id')

                if entity_id is None:
                    continue

                if entity_id.startswith('sensor.'):
                    last_sensor_event[entity_id] = event

            elif event.event_type == EVENT_BLUMATE_STOP:
                if event.time_fired.minute in start_stop_events:
                    continue

                start_stop_events[event.time_fired.minute] = 1

            elif event.event_type == EVENT_BLUMATE_START:
                if event.time_fired.minute not in start_stop_events:
                    continue

                start_stop_events[event.time_fired.minute] = 2

        # Yield entries
        for event in events_batch:
            if event.event_type == EVENT_STATE_CHANGED:

                # Do not report on new entities
                if 'old_state' not in event.data:
                    continue

                to_state = State.from_dict(event.data.get('new_state'))

                # If last_changed != last_updated only attributes have changed
                # we do not report on that yet. Also filter auto groups.
                if not to_state or \
                   to_state.last_changed != to_state.last_updated or \
                   to_state.domain == 'group' and \
                   to_state.attributes.get('auto', False):
                    continue

                domain = to_state.domain

                # Skip all but the last sensor state
                if domain == 'sensor' and \
                   event != last_sensor_event[to_state.entity_id]:
                    continue

                yield Entry(
                    event.time_fired,
                    name=to_state.name,
                    message=_entry_message_from_state(domain, to_state),
                    domain=domain,
                    entity_id=to_state.entity_id)

            elif event.event_type == EVENT_BLUMATE_START:
                if start_stop_events.get(event.time_fired.minute) == 2:
                    continue

                yield Entry(
                    event.time_fired, "Home Assistant", "started",
                    domain=HA_DOMAIN)

            elif event.event_type == EVENT_BLUMATE_STOP:
                if start_stop_events.get(event.time_fired.minute) == 2:
                    action = "restarted"
                else:
                    action = "stopped"

                yield Entry(
                    event.time_fired, "Home Assistant", action,
                    domain=HA_DOMAIN)

            elif event.event_type.lower() == EVENT_LOGBOOK_ENTRY:
                domain = event.data.get(ATTR_DOMAIN)
                entity_id = event.data.get(ATTR_ENTITY_ID)
                if domain is None and entity_id is not None:
                    try:
                        domain = split_entity_id(str(entity_id))[0]
                    except IndexError:
                        pass

                yield Entry(
                    event.time_fired, event.data.get(ATTR_NAME),
                    event.data.get(ATTR_MESSAGE), domain,
                    entity_id)