jazzyisj/unavailable-entities-sensor

New button entites handle incorrectly

Closed this issue · 14 comments

Hey,
a new button entity (e.g. created through https://www.home-assistant.io/integrations/button.mqtt/) has the state Unknown when available. It is currently discovered as a problematic entity by your script. Could you please look into this? Thanks!

grafik

This exact situation (button entity) is covered in the README. Maybe I should just add the button domain in to the ignored groups as the default as I imagine this is going to keep coming up and I really don't see a situation where anybody would want to actively monitor buttons for an unknown state. Honestly I'm not even sure they can have a state of unknown after they have acquired their initial state, I haven't played with them yet.

You can ignore the button domain entirely.

Change this line.

|rejectattr('domain','eq','group')

To this.

|rejectattr('domain','in',['group','button'])

Let me know if this resolves your issue!

Hey Jazzy, I did that as a workaround. However completely ignoring them is not the best solution because Yes unknown shouldn't raise a warning but unavailable should!?

This seems to do the trick. Maybe you know a cleaner way. Feel free to use it.

              {{ states
                |rejectattr('domain','in',['group','button'])
                |rejectattr('entity_id','in',state_attr('group.ignored_unavailable_entities','entity_id'))
                |rejectattr('last_changed','ge',ignore_ts)
                |selectattr('state','in',['unavailable','unknown','none'])
                |map(attribute='entity_id') | list
                +
                states
                |selectattr('domain','eq','button')
                |rejectattr('entity_id','in',state_attr('group.ignored_unavailable_entities','entity_id'))
                |rejectattr('last_changed','ge',ignore_ts)
                |selectattr('state','in',['unavailable','none'])
                |map(attribute='entity_id') | list
              }}

Btw I suppose this filtering logic would be more efficient if you filtered by state first. wdyt? Hard to say for sure without looking at the code

The button entity is stateless, as in, it cannot have a state like the on or off state that, for example, a normal switch entity has.

https://www.home-assistant.io/integrations/button/

So as I understand it, the state will always be unknown. I'm thinking that for most people, simply ignoring the entire domain will suffice. I'm struggling to come up with a use case where a button would even have an unavailable state, other than if the integration that instantiated them does not load at all in which case it won't be the button entities that would be of concern.

Certainly if you wish to monitor your button entities for that possibility, your modification will work. Though I would make the following change so you are not iterating the entire states object twice.

                +
                states.button
                |rejectattr('entity_id','in',state_attr('group.ignored_unavailable_entities','entity_id'))
                |rejectattr('last_changed','ge',ignore_ts)
                |selectattr('state','in',['unavailable','none'])
                |map(attribute='entity_id') | list

I'm struggling to come up with a use case where a button would even have an unavailable state

The button entity is not special in that way. It can be unavailable and it can be the only entity exposed by a device. Hence it would indeed be wise to cover this within your sensor.

button:
  - platform: mqtt
    name: test_unavailable_button
    command_topic: "coffee-machine/brew"
    payload_press: "true"
    availability_topic: "coffee-machine/available"
    payload_available: "online"
    payload_not_available: "offline"

grafik

Huh. Well thanks for pointing that out. Sounds like you're good to go for now but I'm going to leave this open a bit and have a real good look at it when I get a chance to see if I can come up with a better way to deal with it.

Sounds fair.

Maybe one thought to add another perspective: The sensor defined is called "unavailable entities", even though entities with the unknown and none state are listed as well. I might extend your file to generate two sensors, one for "unavailable entities", one for "unknown entities". Within that change I would ignore button for the latter but no special handling is needed for "unavailable entities". Overall sounds like a pretty clean solution to me

You make absolutely valid points and customizing the template, creating additional template sensors and monitoring different states is demonstrated in the README and examples.

With the idiosyncrasies of the new button entity you have pointed out I think I'm going to add some additional documentation and examples for the situation you have outlined here.

For the default sensor itself though, my goal is to keep it as simple and generic as possible in a way that meets the requirements for the majority of people who need it. At the end of the day it's really just a simple template sensor. It just happens to be one that a lot of people starting out with HA want/need and don't know how to create themselves yet. They can drop this package in and get immediate results. Once they've got that there are a lot of hints in the README to refine it a bit so it can meet most people's immediate needs.

I had a look at your git profile here. Something tells me after looking at a few template sensors and the documentation you'll be writing your own templates that will make this one look silly.

I have all kinds of template sensors in my config. A few of them are just variations of this sensor, others more complicated. I'm sure you could use some of these for ideas and starting points to create sensors to meet your needs. As for jinja itself, the home assistant templating documentation covers a lot of what you need in and the jinja documentation is also a great reference.

As for your situation here, if you're like me if you don't get your morning coffee on time it's going to be a bad day. Since it looks like you're already going to go down the road of creating additional sensors you can take it to the next level and create a separate template binary sensor that monitors just the state of your button entity that you can then utilize in both the UI and for an alert entity.

template:
  - binary_sensor:
      - name: 'Coffee Maker Connected'
        unique_id: coffee_maker_connected
        icon: "{{ 'mdi:coffee' if is_state('binary_sensor.coffee_maker_connected','on') else 'mdi:coffee-off' }}"
        device_class: connectivity
        state: "{{ states('button.coffee_machine')|lower not in ['unavailable','none'] }}"

alert:
  coffee_offline:
    name: 'Coffee Offline'
    title: 'Coffee Machine Alert'
    message: 'The coffee maker is offline. Go fix it!'
    entity_id: binary_sensor.coffee_maker_connected
    state: 'off'
    repeat:
      - 5
      - 60
    skip_first: true
    notifiers: thom
    data:
      tag: coffee_offline

Just a thought.

If I can contribute my two cents:

I agree with @jazzyisj in thinking that this sensor should be simple and cover practical use-cases.
Theoretically what @ThomDietrich writes is true, ie. a device can expose an isolated button entity and nothing more. However, practically speaking, I think this will be quite uncommon; even devices with the sole purpose of functioning as a button (eg. IKEA shortcut buttons or Aqara mini switches) would also expose something more (like battery level), which this sensor can monitor.

As suggested here, I also have a few more complicated sensors (looking at devices, areas...), derived from this initial one. But again, they are for my own use-case and therefor have no place in this generic and elegant sensor.

I've submitted a PR #5 implementing an earlier comment by @jazzyisj . Feel free to comment / disagree!

Hey all,
@jazzyisj you are right, I am totally able to build my own template sensors and I am doing just that However, I am a big believer in the power of a community and would always try to find a published and maintained solution for a problem before building something myself. Your published version saved me and many others a lot of time and if anyone finds a bug or room for improvement, everyone benefits from it.

That said, I personally (and I am not trying to convince you) disagree with the argument that "this sensor should be simple". Simple is easy for anyone to build; detailed and all-encompassing is something the community would benefit from. Because of that I also tend to disagree with the PR by @amitkeret as it technically introduces what you could call a "bug" - suddenly the sensor does not list all "unavailable entities" even though it advertises that.

Anyhow, these are just my two cents. All good.
If I were you, I would probably offer two-three versions of the package_unavailable_entities.yaml for users that browse this repository:

  • The simple one to cover simple needs
  • An advanced one with separate unknown and unavailable sensor and other tweaks that might only be relevant for a subset of users
  • A custom set of specialized sensor examples for areas, devices, etc. on which users can build upon.

@ThomDietrich, @amitkeret - So after thinking about it a bit I did decide to include 'unavailable' button entities, albeit with a more simplified template. Documentation has also updated to note the change. I've also pinned this issue to highlight it. Thank you both for the discussion and your contributions.

@ThomDietrich And here I was thinking I was just helping out a new guy when it looks like it was the other way around...lol. (I was just going over the beta release notes and saw your PR for unique_id's on statistics entities.) Cool stuff.

Hehe no worries, but also don't take this too serious. I might have my experiences but you are certainly more knowledgeable when it comes to template syntax. 😉 I'm happy to see your new version of the script, I love the approach.

By the way, I went a bit further and explored the unavailable vs unknown idea. I realized that two independent entities doesn't really cut it and in the end of the day it's really about presentation.
Long story short, in case you would like to add this somewhere in the extended examples or in README, be my guest :)

Improvements:

  • Show state explicitly
  • Name friendly name
  • Sort by friendly name
              message: >
                {% set ns = namespace(result=[]) %}
                {% for s in expand(state_attr('sensor.unavailable_entities', 'entities')) %}
                  {% set ns.result = ns.result + [
                      "**" ~ s.name ~ "**\n"
                      ~ "- *entity_id*: " ~ s.entity_id ~ "\n"
                      ~ "- *state*: " ~ s.state ~ "\n"
                    ]
                  %}
                {% endfor %}
                {% set ns.result = ns.result | sort %}
                {{ ns.result | join('\n') }}

grafik

@ThomDietrich

I've added your detailed message template to the actual package as an alternative to the default.