home-assistant / architecture

Repo to discuss Home Assistant architecture
315 stars 99 forks source link

Add a `cycle_speed` service for fan components #410

Closed alexbarcelo closed 1 year ago

alexbarcelo commented 4 years ago

Context

Having a single-button interface to fan speeds is something desirable in a lot of scenarios (e.g. the switch-cord mechanism that old and not-so-old ceiling fans have, something also seen in bathroom electric heaters).

Right now, there is a set_speed service which requires the speed. I was looking into some no-parameters service call for changing the speed of a fan, which is useful for simple automations (e.g. the ones triggered by a button).

Proposal

I propose to add a cycle_speed service for fan component. That service would cycle along the classical OFF-HIGH-MEDIUM-LOW-OFF, skipping any non-available speed.

It is a simple service, which can automatically be enabled for all components that have speed control, and introduce no breaking change whatsoever.

If that architectural change is accepted, I have a PR proposal implementing that https://github.com/home-assistant/core/pull/38194

Consequences

It becomes easier to set up "single-button interfaces" to fans and the user has a useful tool for implementing basic fan automations in home-assistant. There is no breaking change, and no need for any integration to add this feature, as this can be included in the base fan AFAICT.

alexbarcelo commented 4 years ago

Apologies and thanks to @frenck, as I completely missed this step --I hadn't realized I was changing the basic component infrastructure and thus needed to create this issue here. In retrospective, now it seems obvious to me.

balloob commented 4 years ago

So if this is for just the frontend, we could consider just adding such a button. There would be no need to change the backend for that.

alexbarcelo commented 4 years ago

I was thinking on its usefulness for automations; so no, it is backend.

When I was talking about "single-button interfaces" I was refering to hardware buttons such as Xiaomi Aqara Button or Amazon Dash Button, or ESPHome-DIY-buttons and so on. Sorry for the confusion.

balloob commented 4 years ago

I'm wondering here if we should add a new cycle_X service (And end up adding such a service for every list) or that we should template methods cycle_next and cycle_prev that work by passing in current value and the list of valid values.

{{ cycle_next("low", ["off", "low", "medium", "high"]) }}
{{ cycle_prev(states.input_select.bla.state, states.input_select.bla.attributes.options) }}
alexbarcelo commented 4 years ago

I am not fully grasping this cycle_X approach. What I had in mind was what I did in the https://github.com/home-assistant/core/pull/38194 PR, and in my head it only made sense with fan speeds --people my age have grown with cord-hanging-ceiling fans and cord-hanging-bathroom-heaters that cycle OFF-MAX-MED-LOW-OFF. That was what I was trying to mimic (I believe that dumb bathroom heaters don't fit the home automation landscape, but ceiling fans do, and we are stuck with the ceiling-fans-with-three-speeds historical inertia).

I am not sure if it makes sense for other services, and if it should be coded at a lower level. If you think it makes sense, maybe you are seeing a bigger picture of the forest than me (you know, I am looking at that tree!). But those methods... are you saying them work as service calls? Or be internal methods? Both? And then, having cycle_speed use the cycle_prev? Have the cycle_prev superseed my original proposal?

Sorry for having so many questions!

balloob commented 4 years ago

They would work as template methods. So if you are templating service data, you could just cycle to the next. With a generic approach it will also work for input_select, climate hvac modes or anything else.

l-mb commented 3 years ago

Hm, I can see how that could work, but it also seems kind of ... elaborate rather than concise in the resulting YAML. Given we'd not just want cycle_, but step_up + step_down (without wrapping/cycling around), first, last ...

I can see this being valuable as a generic service for everything that has ordered, discrete states. But instead of needing to pass in both the current state and the list of possible states etc, the very least should be an API for these calls that one can just pass in a state object and that figures out the current and possible states automatically?

balloob commented 3 years ago

That's assuming given any state, we know if we need to cycle the state or an attribute, and that we know the right service to call to change it, and that we know if we need to cycle up or down.

l-mb commented 3 years ago

This would only work for objects that have ordered, discrete values, and can describe themselves. (Numeric values may require a step size.)

Then first/last/next/previous/cycle_up/cycle_down can work directly and concisely. (Such as input_select, which is how I ended up on this issue ;-) ) But it could also work for stepping through, say, the color temp or brightness etc.

Otherwise, yes, it may be necessary to provide the missing metadata, either by annotating the object or specifying/overriding on the call.

frenck commented 1 year ago

This architecture issue is old, stale, and possibly obsolete. Things changed a lot over the years. Additionally, we have been moving to discussions for these architectural discussions.

For that reason, I'm going to close this issue.

../Frenck