-
-
Notifications
You must be signed in to change notification settings - Fork 37.7k
Added mqtt_statestream component #9286
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
e99f235
730d6ea
f87f492
9f75ff1
a34a563
1d9bab9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| """ | ||
| Publish simple item state changes via MQTT. | ||
|
|
||
| For more details about this component, please refer to the documentation at | ||
| https://home-assistant.io/components/mqtt_statestream/ | ||
| """ | ||
| import asyncio | ||
|
|
||
| import voluptuous as vol | ||
|
|
||
| import homeassistant.loader as loader | ||
| from homeassistant.const import EVENT_STATE_CHANGED | ||
| from homeassistant.core import callback | ||
| from homeassistant.components.mqtt import valid_publish_topic | ||
|
|
||
| CONF_BASE_TOPIC = 'base_topic' | ||
| DEPENDENCIES = ['mqtt'] | ||
| DOMAIN = 'mqtt_statestream' | ||
|
|
||
| CONFIG_SCHEMA = vol.Schema({ | ||
| DOMAIN: vol.Schema({ | ||
| vol.Required(CONF_BASE_TOPIC): valid_publish_topic | ||
| }) | ||
| }, extra=vol.ALLOW_EXTRA) | ||
|
|
||
|
|
||
| @asyncio.coroutine | ||
| def async_setup(hass, config): | ||
| """Set up the MQTT state feed.""" | ||
| mqtt = loader.get_component('mqtt') | ||
| conf = config.get(DOMAIN, {}) | ||
| base_topic = conf.get(CONF_BASE_TOPIC) | ||
| if not base_topic.endswith('/'): | ||
| base_topic = base_topic + '/' | ||
|
|
||
| @callback | ||
| def _event_publisher(event): | ||
| """Handle state change events and publish them to MQTT.""" | ||
| if event.event_type == EVENT_STATE_CHANGED: | ||
| try: | ||
| new_state = event.data['new_state'] | ||
| except AttributeError: | ||
| return | ||
|
|
||
| try: | ||
| payload = new_state.state | ||
| except NameError: | ||
| return | ||
|
|
||
| topic = base_topic + new_state.entity_id.replace('.', '/') | ||
| mqtt.async_publish(hass, topic, payload, 1, True) | ||
|
|
||
| hass.bus.async_listen(EVENT_STATE_CHANGED, _event_publisher) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use async_track_state_change |
||
|
|
||
| hass.states.async_set('{domain}.initialized'.format(domain=DOMAIN), True) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi, @pvizeli - I've removed the 'initialized' state. |
||
| return True | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| """The tests for the MQTT statestream component.""" | ||
| from unittest.mock import patch | ||
|
|
||
| from homeassistant.setup import setup_component | ||
| import homeassistant.components.mqtt_statestream as statestream | ||
| from homeassistant.core import State | ||
|
|
||
| from tests.common import ( | ||
| get_test_home_assistant, | ||
| mock_mqtt_component, | ||
| mock_state_change_event | ||
| ) | ||
|
|
||
|
|
||
| class TestMqttStateStream(object): | ||
| """Test the MQTT statestream module.""" | ||
|
|
||
| def setup_method(self): | ||
| """Setup things to be run when tests are started.""" | ||
| self.hass = get_test_home_assistant() | ||
| self.mock_mqtt = mock_mqtt_component(self.hass) | ||
|
|
||
| def teardown_method(self): | ||
| """Stop everything that was started.""" | ||
| self.hass.stop() | ||
|
|
||
| def add_statestream(self, base_topic=None): | ||
| """Add a mqtt_statestream component.""" | ||
| config = {} | ||
| if base_topic: | ||
| config['base_topic'] = base_topic | ||
| return setup_component(self.hass, statestream.DOMAIN, { | ||
| statestream.DOMAIN: config}) | ||
|
|
||
| def test_fails_with_no_base(self): | ||
| """Setup should fail if no base_topic is set.""" | ||
| assert self.add_statestream() is False | ||
|
|
||
| def test_setup_succeeds(self): | ||
| """"Test the success of the setup with a valid base_topic.""" | ||
| assert self.add_statestream(base_topic='pub') | ||
|
|
||
| @patch('homeassistant.components.mqtt.async_publish') | ||
| @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.""" | ||
| e_id = 'fake.entity' | ||
| base_topic = 'pub' | ||
|
|
||
| # Add the statestream component for publishing state updates | ||
| assert self.add_statestream(base_topic=base_topic) | ||
| self.hass.block_till_done() | ||
|
|
||
| # Reset the mock because it will have already gotten calls for the | ||
| # mqtt_statestream 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() | ||
|
|
||
| # Make sure 'on' was published to pub/fake/entity | ||
| mock_pub.assert_called_with(self.hass, 'pub/fake/entity', 'on', 1, | ||
| True) | ||
| assert mock_pub.called |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
hass.components.mqtt.async_publish(topic, payload, 1, True)