There is a dependency chain here; if you want a device, it depends on an entity being in the entity registry (unique id) and a config entry (config entry id). If you bypass the import you can’t get the config entry id. But I’m not interested in talking about the policies, I just wanted to state the fact that yes your code works but it doesn’t follow the guidelines for a integration to be accepted into the core repo. If you want to do stuff as custom components that fine but this thread about the future of yaml is not really relevant for custom components.
Entry id is a unique id, you can generate a uuid and pass it in the config. In my code, I simply pass the entity id. Do note that the objective is not to store this in .storage
, so by default it goes against the policy and that was my point.
And yes, as stated, it’s for a custom component; so no problems. But to the point of the post, how hard would it really be to support YAML with a simple translation like the one I did?
Of course it is easy when you disregard all the guidelines, I don’t think that’s anything to dispute
Guidelines that could be changed since they are set by contributors like you.
This is not an anti pattern, it is a simple Adaptor Pattern that reads configuration.yaml
and adapts the structure to the one in .storage
. This allows to support YAML without any extra additional changes or cost of maintenance on the code base.
In any case, I am not saying it needs to be implemented exactly as how I am suggesting. However, the YAML structure and JSON are equivalent and one can be translated into the other one. That’s what I am advocating for.
To add to this, some official components are indeed using that technique today:
- MQTT Light, MQTT Vacuum, and others under MQTT; use virtually the same code.
- the demo climate, and all the other demos, do the same approach but in viceversa.
-
met weather uses a hybrid approach where
async_setup_platform
massages the data and then both setup methods delegate to the same common function. Relatively similar to cast media_player as well.
So it doesn’t seem like a crazy idea after all, and this is not even an extensive list. Additionally, reviewing a lot of the config_flow
implementations what I have seen is virtually a copy/paste of the code from async_setup_platform
to async_setup_entry
. Hence, this could have been done in even more places if that was of your interest.
Another way to approach it: Your code has mechanisms to send the configuration from component to component. Conceptually, a similar principle can be used to delegate the configuration from async_setup_platform
to async_setup_entry
.
I have yet to hear how this code (or an improved version with the same approach) is bad, affects performance or it is hard to maintain; beyond not being your liking (i.e. disaligned with current guidelines). This only makes me think that the problem is not the cost of maintenance, but other interests.
I didn’t know that.
For me personally it is a question of reasonable maintenance since a majority of issues and support cases was with helping people getting yaml config to work. It is much easier now with all configuration happening through the options flow.
Now that is simply not true.
When things go wrong there is pretty much nothing we can do to help because .storage is undocumented. With yaml it was simple to point out correctIons to misconfigurations.
How is it expensive to maintain this? Could you elaborate? Genuine question.
async def async_setup_platform(
hass, config, async_add_entities, discovery_info=None):
"""Loads configuration and delegates to official integration."""
# Load configuration.yaml
host = config.get(const.CONF_HOST)
name = config.get(const.CONF_NAME, const.DEFAULT_NAME)
region = config.get(const.CONF_REGION)
token = config.get(const.CONF_TOKEN)
# Format it in the new config_entry JSON format.
config_entry = Config(
util.slugify(name),
{
const.CONF_TOKEN: token,
const.CONF_DEVICES: [
{
const.CONF_HOST: host,
const.CONF_NAME: name,
const.CONF_REGION: region,
},
],
}
)
await ps4_media_player.async_setup_entry(
hass, config_entry, async_add_entities)
return True
It is literally getting the config and changing the structure into what async_setup_entry
. It is definitely much less costly than this async_migrate_entry
that it is today needed to avoid breaking the system among changes in syntax.
And to add:
UI First
I 100% agree! Let’s make it UI first. Let’s make sure that everything works in the UI, please.
Now, let’s make it like Lovelace dashboards. Do you want to “edit manually”? At your own risk, expect the system to break, expect lesser support for you and more problems.
However, do you see benefits on it? Let me enable you to use YAML!
Cost of Maintenance
Let’s also make configuration.yaml
optional to avoid burden on those who don’t want to implement it. Let’s not add burden to people.
However, a contributor wants to add a simple fix like the Adapter Pattern above? Let’s encourage it!
It’s the best of both, not either or that we are asking for.
I was talking from the perspective of an integrationsmaintainer
In that case I’d prefer if it was a central implementation than per integration
That’s a good solution. It is harder to implement centrally as the translations may not map 1:1; but if they do, then it’s definitely doable and one of the solutions. Doing it per solution can bring a bit more of nuances into it, but both are possible.
Has any of this been considered during ADR-0010? Can it be considered and discussed?
You could do a custom component that can host integration specific configurations that can do this translation. Maybe start there to try it out
Something like
Configuration:
domain name:
parameters
Could work with both generic configs as well as specific support per domain
For those who are interested, the posts that have been moved under YAML - cost of maintenance in custom components are not really related to Custom Components.
They actually are a response to the original post (on ADR-0010) and arguing against the deprecation of YAML configuration for Integrations.
Some examples of the posts are collected here:
-
Arguments against ADR-0010 rationale on this original blog post.
-
List of user flows broken with the deprecation on YAML on integrations, fully compiled from the 600 posts on these message
-
Proofs of concept supporting the original counter argumentation:
- Experiment to showcase actual cost of adding YAML support
- Experiment to showcase how to leverage the UI flow to generate YAML configuration, also lowering development cost. And also follow ups on the implications for changes in schema.
I am happy to continue the discussions in another post, if we are not allowed to discuss ADR-0010 on the community/blog post about it. However, I wanted to make clear that these were not unrelated to the main thread or related to custom components; but actual arguments to the main discussion here.
For those interested in officially addressing ADR, I’ve submitted an architecture issue to allow YAML configuration optionally. Comments can be done there instead of here as that’s the official channel for these conversations.
I have also submitted another one with a potential solution which advocates for reusing the same schema, set up and partially rely on UI to solve most or all of the problems with the “cost of maintenance”.
There are also alternative proposals. If you have your ideas, you should also feel encouraged to bring them.
One interesting finding:
Harmony (example) still supports YAML as per documentation and code. I have not seen any notifications on my system that this is deprecated or the entity has been migrated.
However, YAML changes will no longer reflect on the system. I’ve done the following test:
- Initial set up
- platform: harmony
name: HarmonyHub
host: !secret harmony_hub_ip
- UI, shows delay 0.4 which is the default value (as per documentation)
- Changed YAML to add
delay_secs
:
- platform: harmony
name: HarmonyHub
host: !secret harmony_hub_ip
delay_secs: 1
-
Restarted system, for YAML configuration to update.
-
UI still shows 0.4.
As per my discussions with OnFreund, this seems to mean that my entities have been ported from YAML to UI. However, I do not think I have received any notification on my system about it; and, as stated, this component still supports YAML.
If I was a user who do not check Blog or Community, how was I supposed to pick this up?
This feels broken and not working as intended. Can someone else replicate this?
You understand that the UI and Yaml are separate configurations correct? I.E. UI does not impact yaml and yaml does not impact UI. You as a user choose one or the other, not both.
Hi @petro, I understand that.
Now, I have never configured Harmony on the UI, or clicked any migrations. My configuration is solely YAML.
Additionally, Harmony still has configuration available for YAML, as you have happily copied from the documentation.
As such, why do I have the UI if “yaml does not impact UI”? The entity was migrated from YAML to UI without my changes. At the moment, I have my configuration.yaml
where I still have my configuration, but this configuration is useless. I do not have any messages telling me or confirming that my entities have been migrated.
From a technical perspective, OnFreund provided a confirmation and answer here. You may want to have a look.
Hence, yes, YAML has actually affected the UI; but only for a one time configuration and not for further changes.
That’s not entirely true.
There are many integrations that due to the deprecation of yaml are having their yaml configuration automatically imported into the UI. Then after that their yaml config is completely ignored.
The most recent one I remember that affected me was the ZHA integration. In my system it is displayed as a UI configuration but I never migrated anything to the UI and my configuration.yaml still contains my zha: config. And as a test I just removed the zha: section from my manual config and the UI config is still there and my devices still work.
Of course it doesn’t go the other way tho.