In my recents PRs, I got responses that my changes add unnecessary complexity to the components, since the same functionality could be achieved through configuration. In one case, it was a keep alive property for a thermostat (which could be achieved through automation), and in another it was a feature to allow templating values of a specific sensor prone to misadjusted values (which can be alleviated via an additional template sensor).
It’s obvious to me that there’s a recurring theme to this: I value clean, concise configuration files, and prefer to stuff the more complex logic inside the components. On the other hand, the developers who were against the changes seem to think of those changes as unnecessary complications, since they can be resolved by existing means via configuration (albeit a more complex one).
I understand and agree that it’s desirable to keep the components as simple as possible (as long as they provide the required functionality). But surely, allowing for a cleaner configuration file has to be important and prioritized? And if not, where do you draw the line? After all, quite a lot of existing component functionalities can be achieved via complicated combination of automations, inputs, and templates… So when is it OK to resolve a certain complex automation into a built-in behavior inside a component, and when is it not?
There is no golden rule of where we draw the line. But here are some guidelines:
Each platform should do one thing. Either bring in data, process data or automate data. When we start conflating concerns we end up with a complicated platform that can be in a lot of different states because of different permutations of the config:
Makes it more difficult to enhance the platform
Makes it difficult (if not impossible) to make an understandable config screen
An example of what I am trying to avoid is this screenshot of the “simple” preferences pane of VLC:
I agree that reaching a point where the configuration screen (I assume you mean the YAMLs) is as complicated as the example above is undesirable. That is definitely something I’d like to strive towards, as well. And that was also the rationale behind the changes that I proposed. I was simply considering the length and complexity of the final configuration, as opposed to the complexity of the documentation/configuration of a single component.
I still believe that it is better to provide more configuration options to a component, allowing the end users to use the component in a standalone mode, instead of requiring them to combine several less advanced building blocks. I understand that it’s a slippery slope which might end up with huge blob objects combining way too much unrelated functionality. Therefore, I would say that a better approach would be to allow additional configuration for components, as long as it defines behaviors that are logically the responsibility of the component (e.g., if a sensor is prone to being uncalibrated, it’s up to that component to provide a mechanism for calibration, since component is responsible for providing correct data, IMO).
Nonetheless, I’ll take the above guidelines into account in my future pull requests.
With config screen I am talking about a configuration UI. We made a start in the last release and the idea is to keep extending it.
There is another reason to be against adding more complexity to platforms/components. Most of the times, these complexities / new features are actually adding escape hatches allowing experienced users to workaround issues instead of contributing fixes.
The rule of thumb is pretty much that if you can do it with a template sensor/switch, it should be done with that. Each platform/component should either bring in data, process data, automate data or provide an abstraction for platforms.