Skip to content

Added mqtt_statestream component#9286

Merged
pvizeli merged 6 commits into
home-assistant:devfrom
mw-white:mqtt_statestream
Sep 11, 2017
Merged

Added mqtt_statestream component#9286
pvizeli merged 6 commits into
home-assistant:devfrom
mw-white:mqtt_statestream

Conversation

@mw-white
Copy link
Copy Markdown
Contributor

@mw-white mw-white commented Sep 4, 2017

Description:

This PR adds an mqtt_statestream component that publishes state changes to discrete MQTT topics. My use case for this is that I have a number of external systems (including small ESP8266-driven displays) that need to monitor only certain entities. With this component, I can subscribe those displays only to the topics that they need instead of the whole event stream.

For example, with a base_topic configured as hass/states, turning on light.master_bedroom will publish on to hass/states/light/master_bedroom.

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#3302

Example entry for configuration.yaml (if applicable):

mqtt_statestream:
  base_topic: hass/states

Checklist:

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable ([example][ex-requir]).
  • New dependencies are only imported inside functions that use them ([example][ex-import]).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

If the code does not interact with devices:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • Tests have been added to verify that the new code works.

@homeassistant
Copy link
Copy Markdown
Contributor

Hi @mw-white,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

Copy link
Copy Markdown
Member

@pvizeli pvizeli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


hass.bus.async_listen(EVENT_STATE_CHANGED, _event_publisher)

hass.states.async_set('{domain}.initialized'.format(domain=DOMAIN), True)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, @pvizeli - I've removed the 'initialized' state.

@lwis
Copy link
Copy Markdown
Member

lwis commented Sep 4, 2017

Is there any reason why you can't use https://home-assistant.io/components/mqtt_eventstream/?

@mw-white
Copy link
Copy Markdown
Contributor Author

mw-white commented Sep 4, 2017

Is there any reason why you can't use https://home-assistant.io/components/mqtt_eventstream/?

Hi, @lwis - the mqtt_eventstream component works really well for linking together Home Assistant instances, or in cases where I want to look at a lot of different entities or events. However, for cases where I'm just interested in getting updates for one or two entities, it's a bit of a firehose. I have to process each message to see if it's one I'm interested in, and on low-power devices like Arduinos or ESP8266-based boards, it's not efficient. The mqtt_statestream component lets me just subscribe to the particular entities that I am interested in for that particular device.

A real-world example from my setup - I have a small panel in my kitchen with 6 addressable LEDs and an ESP8266 controller. The controller subscribes to the entities for my locks and garage doors, and shows the current locked/unlocked status for everything. I know I could rework it to be 'push' based - have Home Assistant control the LEDs and use automations to flip them, but I prefer the other way.

I hope that answers your question...

@MartinHjelmare
Copy link
Copy Markdown
Member

I like the idea of creating the topics from the entity ids.

@lwis
Copy link
Copy Markdown
Member

lwis commented Sep 4, 2017

I'm wondering if this should be a different option for eventstream to avoid overlap, but if it's purpose is to link HA instances then it conflates the component.

I've always preferred discrete topics, because you can always wildcard to get the 'firehose'.

@mw-white
Copy link
Copy Markdown
Contributor Author

mw-white commented Sep 4, 2017

I thought about adding it to eventstream, but I can see wanting to use both modes (in fact, I am using both right now...)

@fabaff
Copy link
Copy Markdown
Member

fabaff commented Sep 4, 2017

This PR pushes in the same direction as #1518 was. I see that splitting state updates to different topics could be useful for a specific use-case.

@lwis
Copy link
Copy Markdown
Member

lwis commented Sep 4, 2017

Hmm, I don't like the overlap as this can also be fulfilled by an automation that is triggered on all state changes.

Maybe this should use case should remain as an automation/custom component as I feel a breaking change (as much as I agree with it) of the eventstream component could be disruptive.

@mw-white
Copy link
Copy Markdown
Contributor Author

mw-white commented Sep 4, 2017

Not sure what you mean about breaking change to eventstream - this is a completely separate item.

And I suspect that a large percentage of current components could be handled by an automation, but I think having an actual component makes it a bit more user-friendly. Not a big deal - I am fine keeping this in my tree.

return

topic = base_topic + new_state.entity_id.replace('.', '/')
mqtt.async_publish(hass, topic, payload, 1, True)
Copy link
Copy Markdown
Member

@pvizeli pvizeli Sep 5, 2017

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)

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)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use async_track_state_change

@balloob
Copy link
Copy Markdown
Member

balloob commented Sep 7, 2017

I think this is a great idea 👍

@pvizeli pvizeli merged commit 31f189d into home-assistant:dev Sep 11, 2017
@aderusha
Copy link
Copy Markdown

This is huge, because the way that mqtt_eventstream works is an anti-pattern for MQTT. Having everything broken out into individual topics allows the broker to (optionally) retain messages for each state, allows clients to selectively subscribe to individual states (and hopefully attributes at some point), and doesn't create enormous 1k+ JSON objects which can be difficult for embedded systems with limited memory to handle (the entire purpose of MQTT, and something which the commonly-used library PubSubClient struggles with).

@balloob balloob mentioned this pull request Sep 22, 2017
@mw-white mw-white deleted the mqtt_statestream branch September 24, 2017 04:54
@home-assistant home-assistant locked and limited conversation to collaborators Mar 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants