Skip to content
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

Group platform definition #13

Closed
OttoWinter opened this issue Feb 20, 2018 · 20 comments
Closed

Group platform definition #13

OttoWinter opened this issue Feb 20, 2018 · 20 comments

Comments

@OttoWinter
Copy link
Member

OttoWinter commented Feb 20, 2018

So interest has been shown in implementing "group" platforms for several PlatformComponents. To recap, group platforms are platforms that encapsulate and proxy the state of several "child" entities. (Just like Hue, ... light groups)

screen shot 2018-02-19 at 22 19 51

For example, if I have four lights along the corners of my room, I could now (using "light.group") let them show up as one in the front-end.

While I personally love this feature and can't wait for it be added, we definitely shouldn't rush this. We should first try to define what a "group" platform is, how the user expects it to behave, and how configuration should look like.

During this post I will mostly be referring to grouped lights, as that's the component I'm most familiar with. If there are other components that need different configs/behavior, please contribute.

I think our first concern should be abaut how a user expects the group to behave (maybe mimic the behavior of Hue, ... groups) and only then what features it should support.

Related: home-assistant/core#12229, home-assistant/core#11323, home-assistant/core#12303

Behavior

Features: Union / Intersection

So I think first we should define whether the functionality of a group is the union or the intersection of the features of its child components.

For example, if we're setting up several lights into a group, like all lights in the 1. floor, if one of the grouped lights doesn't support RGB colors and all others do, should we disable colors for the entire group? I think this would eventually happen quite often as light groups are potentially great for combining lights of different domains (for example Hue and MQTT lights). Maybe we could even add a configuration option to control this.

State reporting

Next, we should define what state should be reported to the front-end. For example, for a light it would IMHO make very little sense to report the average brightness of all child lights. So one option is to report the state of the first entity - another option would be to report the state of the first entity that is on. Maybe we could even have a "leader" option in the configuration to select this. If one light is on, should we display the whole group as on (as we do in the "normal" groups)? There are many different ways of doing this, and also one of the things we should really be consistent about.

As another example, in lights, should we report all possible effects you could set as effect_list? Should we use the minimum possible min_mireds value or the value of the leader. If we call light.toggle on a light group, should we use our reported state to sync all lights to be of the same state after the toggle, or should we toggle each light individually (probably not too good IMO). So another question: Should we always try to sync the state of all children?

Initial state

Also: What do we report when no child entity has a state yet? Personally I would advocate for STATE_UNAVAILABLE since that also visually shows in the front-end that you can't control it.

Configuration

Ideally, the configuration would look more or less exactly the same between different components. And I personally also think we should keep customization at a minimum and the default behavior "as dumb as it gets". Why? We have the template platforms to do more complicated stuff and lots of customizability will just scare off users IMHO.

So, do we want the configuration to look something like this: ?

light:
  - platform: group
    name: Cool Light Group
    entities:
      - light.amazing_light
      - light.foobar
      - light.sun

Are there any other features groups should definitely support? Anything we should consider concerning other components?

Front-end support

This is very much a hypothetical, but as @balloob said "We might even add frontend support for "group" platforms to show the child entities." I think we should at least think about how it should be done.

@andrey-git
Copy link

How is this different from today's group?

@OttoWinter
Copy link
Member Author

@andrey-git group.* currently only really supports setting states with services. What these new group platforms do is that they additionally report the states of their child entities so that they can be used better in the front-end and in state checking. (see home-assistant/core#12229, home-assistant/core#11323, home-assistant/core#12303 for reference)

You can think of them kind of like Hue light groups (or light groups of any other make) in Home Assistant. Additionally, with this you would now be able to create light groups (or other components) across domains.

@cdce8p
Copy link
Member

cdce8p commented Feb 20, 2018

The complete idea is to group components (lights, covers, ...) so that they appear as just one component. Although this is already supported with a mix of templates, template sensors and scripts, a own platform would make it a lot easier to set up. For reference a while ago I added an example to the template cover doc. With a separate platform the config would look more like what @OttoWinter wrote above, which would be awesome.

As already linked above (home-assistant/core#12303), I submitted a PR for something similar for covers. I wasn't and still am not sure though if group would be the right name, due to the resemblance to groups.

Features: Union / Intersection

I think the component group should support a basic set of operations at default (like all cover features, for covers) and additional functions should be parameters (e.g. tilt features). Important would be to find the right balance (not: set_position, tilt, tilt_position, ...). If some components don't support a certain function it shouldn't effect all others (like set_cover_position should only effect covers that support the function, all others should ignore the command).

State reporting

IMO it would make very little sense to report just the attribute of a selected leader for the whole group. It could be an idea to report default values if the attribute varies from component to component (brightness = 100 if on, 0 else) and the exact number if all are the same. An alternative could be to make this configurable: the option described before, always the minimum or maximum value (default, min, max). If some don't support a certain attribute, just ignore them in this case (they don't have it to begin with and you probably already know that).

Configuration

Looks good to me.

Front-end support

I'm a bit skeptical about it. The whole idea of this platform is to group components so that they appear as one and are as such available to automations and scripts. Only because you are using this feature, dosn't mean that you have hidden all the other components. A dedicated state-card might not be what somebody might want who is looking for this.

These are a few of my thoughts about it. As @OttoWinter already said: I would also really love to see this being added to Home Assistant.

@andrey-git
Copy link

Does this mean that the new group are by design single-domain?
Would this be able to replace current groups as far as backend is concerned? (I.e. we would be able to remove the ability to call services on kegacy groups)

@balloob
Copy link
Member

balloob commented Feb 20, 2018

These groups would be single domain and be implemented as platforms for that domain. This has the great benefit that each group platform is able to group attributes and states appropriately. The current "group" is doing a poor job because we don't want to add too much component "knowledge" in it.

In the frontend we have two hacks in place currently:

  • for a single domain group, render the more info for the first state
  • show a toggle to turn group on/off

One glaring issue with current group design is that combining states is all off as binary sensor "ON" gets mixed with a light "ON".

Features: these should be union. We should be able to control any aspect of any child light via a group. When 1 light is on, the group light should be on. When 1 light has a color, the more info should allow picking a color etc.

State reporting: we should not do things like first light that is on kinda things. That is confusing to the user. I think that it depends on the domain and attribute how it should be handled. I honestly think that averaging the brightness is not a bad idea at all. If you have 3 lights next to one another, isn't that what you would expect to happen?

For frontend, I wouldn't mind showing entity state info's in the more info (like group does today). In fact, we could add this today for any entity that has an entity_ids attribute?

@MartinHjelmare
Copy link
Member

This group platform should be single domain yes (platforms are always single domain).

@OttoWinter
Copy link
Member Author

OttoWinter commented Feb 20, 2018

These groups would be single domain and be implemented as platforms for that domain.

That's right. One question that arose in light.group was whether we should actually check if all child entites are lights. I mean theoretically users could add switches to that domain and it would still work. Should we actively check that?

I honestly think that averaging the brightness is not a bad idea at all.

True, the brightness does make sense. I'm not so sure about averaging RGB or even XY colors though.

This group platform should be single domain yes (platforms are always single domain).

I think I mixed up my lingo there before. What I meant was that now you would be able to combine lights from different manufacturers/components like Hue and MQTT and create light groups together. Before, within one such ecosystem such as Hue, this was already possible, across ecosystem not so much though.

Does anybody know about how other products/manufacturers do grouping (such as light groups)? I mean it would certainly be worth a look to see how they've done it and maybe learn some limitations of different systems.

@balloob
Copy link
Member

balloob commented Feb 20, 2018

We should actively check that all entities belong to same domain. Make it part of config validation that you check domains of passed in entities.

@cdce8p
Copy link
Member

cdce8p commented Feb 20, 2018

Average brightness

Does make sense, but it should depend on the attribute. If you group all covers on the first floor, some open, some closed, it dosn't make sense to report current_position as 50 for example.

@NovapaX
Copy link

NovapaX commented Feb 20, 2018

We should actively check that all entities belong to same domain. Make it part of config validation that you check domains of passed in entities.

but why? Will it serverely break if we call turn_on on a entity that doesn't support it?
What if I have a smart wall switch (in the switch domain) with a classic light bulb that I also want to turn on?

@cdce8p
Copy link
Member

cdce8p commented Feb 20, 2018

but why? Will it serverely break if we call turn_on on a entity that doesn't support it

@NovapaX As far as I Know: Yes, Home Assistant throws an error if a service is called on an entity that doesn't it. To check if a feature is supported, the state attribute supported_features works. This is however limited to just one domain, since every domain has their own set of values for supported_features.


Another question regarding supported features is, when to check them? Since a group platform would already listen to state changes from every of its entities to update the state accordingly, it could make sense to store the information in a dictionary with the mapping feature --> entities.

@balloob
Copy link
Member

balloob commented Feb 21, 2018

A light group will not allow any other entities. We would make the same mistake as our current group component all over again.

@NovapaX
Copy link

NovapaX commented Feb 21, 2018

I see, makes sense. becomes unmaintainable fast. Such a case (adding a different kind of entity into such a group) could be covered with for example a template light.

@NovapaX
Copy link

NovapaX commented Feb 22, 2018

I was also thinking about how this would be a great thing for device_trackers
So you can group multiple device_trackers (for a single person) and add some conditions like delays, combination of devices away/home to determine the state of the device_tracker.group

And if we look at #14, we could steer away from using generic groups as much as possible. (there are still some use-cases maybe, but these are probably better served by some kind of template.group)

So to keep this on-topic. I think behaviour of domain.group could (and should) differ between domain depending on the nature of the domain, and in some cases be configurable. Configurable should be simple, but useful. If things get too complicated it should be done in a sensor or custom component.
Behaviour should, of course, be described in clear wording in the documentation.

@balloob
Copy link
Member

balloob commented Mar 5, 2018

I think that we can close this issue?

@OttoWinter
Copy link
Member Author

OttoWinter commented Mar 19, 2018

I thought I'd write a short summary of these points (also partially based on how I did it for light groups). Each of these rules are only recommendations, and can of course be changed on a per-component basis if it makes more sense.

Group platforms should:

  • be called {} Group by default. For example Light Group.
  • strictly only allow entities from their own component (see Group platforms - mixed domains #18). For example, Light Groups only accept light.* entities, not input_boolean.* as members.
  • look like any other entity of the component in the front-end.
  • do all their supported features based on a union of the supported features. For example if one light in a light group supports rgb, the entire group supports rgb.
  • always try to sync the states of the children. For example toggling a light group with states A: on, B: on, C: off, should result in A/B/C: off.
  • report their state intelligently. For example for light groups: the average brightness of all lights that are on; and the most common active effect amongst all members.
  • report unavailable if no child entities have reported any states.
  • have a configuration format like this:
component:
  - platform: group
    name: Custom name
    entities:
      - component.entity_1
      - component.entity_2
  • can have additional configuration options where it makes sense, but that should be kept to a minimum.

Components where a group platform would make sense (there might be others too):

@dgomes
Copy link

dgomes commented Mar 19, 2018

🖐 I will work multiple climate devices if needed

(have a thermostat per room and could use a group to set away mode on/off)

@cdce8p
Copy link
Member

cdce8p commented Mar 19, 2018

I was thinking: Isn't the min/max sensor also some sort of a group platform?

@balloob
Copy link
Member

balloob commented Mar 19, 2018

@cdce8p Sensors are a different category. They don't have features/functions. They have indeed a wide range of "grouping" or 2nd order platforms already, like filter, statistics etc.

@austinlg96
Copy link

austinlg96 commented May 16, 2018

I think it would be convenient if we could define alternative behavior for controlling the groups as a whole too. For example, I use the Osram Lightify hub and when I create a group of Lightify lights in homeassistant it (apparently?) sends an individual request for each bulb to the hub. This results in a very noticable delay between each light changing. However, if the group is created in Lightify and then imported to Home Assistant as a single entity, everything is perfectly uniform..

I'm imagining something like:

component:
  - platform: group
    name: Custom name
    entities:
      - component.entity_1
      - component.entity_2
      ~- component.entity_3
    controllers:
      - components.entity_1
      - components.entity_4

In this example, components.entity_4 could be an external grouping of components.entity_2 and components.entity_3. If that homeassistant group received the turn_on command, it would issue components.entity_1.turn_on and components.entity_4.turn_on.

Edit: Just realized this is closed. Awkward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants