Allow ignoring call service events in mqtt_eventstream (#12519)

* [WIP] Allow ignoring call service events

This allows a setting a configuration value (False by default to continue the current behavior) which will ignore call service events.

* extra spaces

removed them

* updates from PR review

* removed print

* update spacing

* updated allowed events to allow for custom events, and included some tests

* hound fixes

* Remove unused constant

* Lint
This commit is contained in:
Mike Megally 2018-02-22 02:19:18 -08:00 committed by Lukas Barth
parent 4fdbbc497d
commit f0a1beac5d
2 changed files with 65 additions and 1 deletions

View File

@ -26,6 +26,7 @@ DEPENDENCIES = ['mqtt']
CONF_PUBLISH_TOPIC = 'publish_topic'
CONF_SUBSCRIBE_TOPIC = 'subscribe_topic'
CONF_PUBLISH_EVENTSTREAM_RECEIVED = 'publish_eventstream_received'
CONF_IGNORE_EVENT = 'ignore_event'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
@ -33,6 +34,7 @@ CONFIG_SCHEMA = vol.Schema({
vol.Optional(CONF_SUBSCRIBE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_PUBLISH_EVENTSTREAM_RECEIVED, default=False):
cv.boolean,
vol.Optional(CONF_IGNORE_EVENT, default=[]): cv.ensure_list
}),
}, extra=vol.ALLOW_EXTRA)
@ -44,6 +46,7 @@ def async_setup(hass, config):
conf = config.get(DOMAIN, {})
pub_topic = conf.get(CONF_PUBLISH_TOPIC)
sub_topic = conf.get(CONF_SUBSCRIBE_TOPIC)
ignore_event = conf.get(CONF_IGNORE_EVENT)
@callback
def _event_publisher(event):
@ -53,6 +56,10 @@ def async_setup(hass, config):
if event.event_type == EVENT_TIME_CHANGED:
return
# User-defined events to ignore
if event.event_type in ignore_event:
return
# Filter out the events that were triggered by publishing
# to the MQTT topic, or you will end up in an infinite loop.
if event.event_type == EVENT_CALL_SERVICE:

View File

@ -30,13 +30,16 @@ class TestMqttEventStream(object):
"""Stop everything that was started."""
self.hass.stop()
def add_eventstream(self, sub_topic=None, pub_topic=None):
def add_eventstream(self, sub_topic=None, pub_topic=None,
ignore_event=None):
"""Add a mqtt_eventstream component."""
config = {}
if sub_topic:
config['subscribe_topic'] = sub_topic
if pub_topic:
config['publish_topic'] = pub_topic
if ignore_event:
config['ignore_event'] = ignore_event
return setup_component(self.hass, eventstream.DOMAIN, {
eventstream.DOMAIN: config})
@ -144,3 +147,57 @@ class TestMqttEventStream(object):
self.hass.block_till_done()
assert 1 == len(calls)
@patch('homeassistant.components.mqtt.async_publish')
def test_ignored_event_doesnt_send_over_stream(self, mock_pub):
""""Test the ignoring of sending events if defined."""
assert self.add_eventstream(pub_topic='bar',
ignore_event=['state_changed'])
self.hass.block_till_done()
e_id = 'entity.test_id'
event = {}
event['event_type'] = EVENT_STATE_CHANGED
new_state = {
"state": "on",
"entity_id": e_id,
"attributes": {},
}
event['event_data'] = {"new_state": new_state, "entity_id": e_id}
# 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.block_till_done()
assert not mock_pub.called
@patch('homeassistant.components.mqtt.async_publish')
def test_wrong_ignored_event_sends_over_stream(self, mock_pub):
""""Test the ignoring of sending events if defined."""
assert self.add_eventstream(pub_topic='bar',
ignore_event=['statee_changed'])
self.hass.block_till_done()
e_id = 'entity.test_id'
event = {}
event['event_type'] = EVENT_STATE_CHANGED
new_state = {
"state": "on",
"entity_id": e_id,
"attributes": {},
}
event['event_data'] = {"new_state": new_state, "entity_id": e_id}
# 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.block_till_done()
assert mock_pub.called