[wip] Allow configuration parameter updates to be suppressed#5326
[wip] Allow configuration parameter updates to be suppressed#5326andrewfg wants to merge 6 commits intoopenhab:mainfrom
Conversation
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
…enhab-core into dynamic-config-param
Signed-off-by: Andrew Fiddian-Green <software@whitebear.ch>
|
Quoting myself from #3753:
I'm also thinking that perhaps it should be a per-Thing setting instead of a binding property. I'm pretty sure that even in the bindings where it is "used as a feature", it can also act as a bug. But, I guess there is no way to make a Thing setting that applies to all Things (with discovery)? |
In this PR it is neither "per binding", nor "per Thing", nor indeed a "setting". Instead it is per xml configuration parameter definition per a given thing-type xml. EDIT: so just for the avoidance of doubt: the addon author can define in their thing-type xml exactly which configuration parameters of which thing-types shall be subject to automatic updating by discovery services and which not. So with a particular binding you may have some thing types which have some config params which are (say) not subject to automatic updating. See link => LINE 331 |
It's what I meant by "per binding". The point is that the add-on author must decide, while for example in the case with the Chromecast, there are situations where both variants are desired. So, I was saying that perhaps it would make more sense as a user setting somehow - per Thing, not Thing-type. But, it might not be easy to do. |
Probably we need both.
And not per Thing .. it needs finer granularity -- per config param of a thing (-type) |
What I meant was "per Thing instance" - so that you could e.g. have one Chromecast that updates and one that doesn't - depending on if it's a dynamically created group or a device with a fixed (DHCP assigned) IP. I'm just not sure if there is any mechanism to do it on that level? We can't add this as a configuration parameter to all Things..? |
Currently I am thinking only of the static thing-types. I have not (yet) thought about dynamically created things based on dynamically created thing-types. But let me think about it.. |
That wasn't what I meant, but that's also a case to think about. With Chromecasts (and I bet other devices too), the devices themselves can create "dynamic devices" (that are announced via mDNS) in addition to the physical devices. Those need to be dynamically updated as their IP and port will change when the Chromecasts "feel like it" (they have "elections" over who is the "leader" of a group, and when the group leader changes, so does the IP and port of the group). |
So the current behaviour works fine for these already? .. this PR is focussing on suppressing the current behaviour when it is specifically NOT required. |
No, which is my point, what is a "feature" for one device, can be a "bug" for another, even for the same type of device. In the case of Chromecasts, you can't control what the devices announce via mDNS. They just love IPv6 for example, and I've seen examples of "feature" leading to the configured IPv4 address being replaced by a IPv6 address. The problem is that the IPv6 address isn't actually "in use", the network only uses IPv4. So, automatically "updating" the IP to the IPv6 address results in losing connection with the device. So, for the very same type of device, it can be desirable and not be. Which is what I'm trying to say. This isn't something the binding developer can predict, it depends on conditions on the local network. Which is why the only way to get it to work "correctly" for everybody, is to give the user the option to control it. |
|
So are you saying that there is no worth in this PR that allows developers to suppress auto update on certain configuration parameters on certain thing types? And that the only solution that should be pursued is your hoped for user based manual suppression? Personally I think that this PR is a worthwhile step forward. And also, like you, I am not sure if your solution is even actually possible. |
I'm saying that I can only see it working "for everybody" if the users can decide. How to get there, I'm not sure. I still think that there might be no way around the bindings handling it themselves to make it work optimally. As such, this PR could be a useful tool, since bindings that do implement this "properly" could then turn if off for its thing-types. In the end, whether the user want configuration settings to be updated automatically based on "some service" depends quite a lot on the design of their local network - and to some extent on the behavior of the devices. I know that it doesn't exclusively relate to network configuration, like with the mentioned Astro location (but why would that move?), but by and large, I think it applies to IP and port. |
|
@andrewfg I am not sure I see the point in this PR. If a binding author doesn't want the parameters to update, he can have a shadow copy of the properties he does not want updated. The first time the thing is initialized, these will be empty. The binding then copies over values. Automatic updates will not impact these copied values. So there is a workaround. Admitted, your logic could simplify it. There should be a configuration parameter that allows to disable background discovery on a binding level (it was there in the past). It is not exposed in the UI to my knowledge. But I think what you would want is a thing configuration parameter that toggles automatic updates, not background discovery. I don't see an issue with create such a parameter. But it is a bit of work:
|
I must say that I think having all (affected) bindings implement such a workaround seems a bit optimistic. I get that it works well for you, it does not for me. I always control my network, so I have reserved fixed IPs for devices that I want to reach in DHCP. They will thus always come back with the same IPv4 address. IPv6 is actively disabled everywhere possible, and isn't routed, because of the security implications of using it. But, not everything will let you disable IPv6, some will "self assign" one and then announce that IP. When the configuration "auto updates" they become unreachable. I'm sure there are other situations where problems arise as well. I'd say that when you manually configure a device, you don't expect the configuration values to be overwritten. So, while I see the "convenience" of being able to track devices that are assigned new IPs, I think the implementation is shady. It should have been something you'd actively enable, not something that just does what it does without your permission or knowledge.
Nobody says that you don't want background discovery if you don't want the configuration to be updated. Those are completely separate issues. Discovery finds devices for you, and puts them in your inbox. You then manually choose if you want to make those discoveries into Things. From that point on, they should be unafilliated with discovery as I see it. There's no reason for a user to assume that "new discovery results" will interfere and change the Things you have already configured. |
@mherwege I appreciate your inputs. But .. .. The place where I discovered this issue is in the HomeKit binding, where the mDNS discovery (due to a bug that @Nadahar has found in OH Core) may "discover" a thing before the mDNS ServiceInfo has actually been fully qualified. That means that the discovery service would wrongly update the Thing's Config Param to have an IP address of "null". Thus causing the Thing wrongly to go offline. Also there was another similar issue where the mDNS discovery might wrongly update the Thing's Config Param to have an ipV6 address, which since the HomeKit protocol only works on ipV4, also causes the Thing wrongly to go offline. My initial thought, (and hence the reason for this PR), was that I could most easily suppress such unwanted shenanigans via a switch in the Thing's config xml description. (But in the meantime I solved it another way via code in the mDNS discovery participant instead).
Indeed. And I think that this PR is indeed actually the work for 1., 2., and 3. that you cited above. Or?? .. So the "only" additional work is item 4. above .. which I would anyway defer to you ;) .. |
|
I very much appreciate that you picked up this topic! I had it on my to-do list since end of last year when we ran into issues that autodetect reconfigured existing things in KNX binding (basically breaking those things which needed a manual config change after the initial detection). What I actually like to have for KNX is to have this setting per parameter. Let me give some context: Other fields of the config should be updated. The things have a unique serial, so we can identify the hardware and update other configuration parameters like the IP address if it changes over time. This is already happening automatically if I use the serial as unique identification and add the IP during detection. The automatic update is already happening in the background - the binding developer IMHO cannot do much to avoid it besides not adding the respective config parameters. Someone - I thinks it was Kai - made the proposal to extend the xml, as you just did. But maybe we need to change this from thing to parameter level. |
That is actually what the current code does (to be strict is per parameter instance). |
|
@holgerfriedrich I believe @andrewfg proposal is on parameter level. The challenge I see is with the UI. That’s a much more challenging enhancement then doing it on thing level. The UI then has to have a switch for every parameter to turn this on/off for every possible type of parameter. That’s I believe where I disagree with @andrewfg (I preferred thing level, not thing config parameter). But as I understand it for the KNX case you would also want that. @andrewfg I think where we are not in line is that your dynamic parameter is static in the thing type. It is not controlled by a UI flag you can switch on/off per individual thing config parameter. The binding developer fixes it. Controlling this in the UI for each parameter I think is making it far heavier than needed. And also think about controlling this flag in textual thing definitions then. @holgerfriedrich In the binding, can’t you use a shadow configuration parameter that, once set, overrules the main discovered one in the binding logic? |
Sort of. I imagine it could be read only on unmanaged things, but perhaps modifiable on managed ones. Or ?? But indeed the basis of your concern is that we are talking essentially about a "configuration parameter for a configuration parameter". In thing type xml we do already configure such config params by applying an xml attribute on the EDIT however I think there is not really a problem here. When the Thing is initialized the |
|
I must just repeat what I have said previously. I don't think there is a general solution that fits every use case here. Different bindings have different challenges. Many bindings aren't even affected, does this apply to bindings that don't use mDNS or UPnP discovery at all? Perhaps SDDP as well, but there are a limited number of ways IPs and ports can be "detected". I think those are the two parameters really in play here - I know that the "location" in Astro has been used as an example as well, but I frankly think that people can manage to update this themselves every time they buy a new house. So, when narrowing it down to the bindings and parameters where it's actually relevant, it might not be that many. For some bindings it's clearly undesirable, in other situations it will depend on the user's network setup. The exact way it is applied will probably have different nuances in different bindings. Let's not forget that this only works if the ThingUID happens to be whatever discovery suggests as well. It's a "hidden option" that users have no idea that they are choosing to enable or disable when they choose the ThingUID. I think the only "proper" way to manage this is that the bindings does it themselves, independent of discovery. They can subscribe to updates from the same services, and apply updates as appropriate. They can make the configuration options necessary to let the users decide. I know that this is a "longer path" and that a "quicker fix" is desired, I just don't see that a "quicker fix" can ever be satisfactory. A way to disable this per binding (by the binding author) could then be a way to transition bindings that implement this themselves gradually, without breaking existing functionality. |
|
My request is quite simple for the UI - no change needed at all. For me it would be sufficient to have it decided by the binding developer and hard coded in the XML. Basically marking all config parameters which should not be touched by the automatic update process. |
The problem is that if you look at the different needs overall, that won't do. |
|
Let's also not forget that |
|
For reference, I ran a grep over all official bindings that has It was somewhat more than I expected, but it's not at sure certain that all are affected. I believe that they must also generate "reproducable" UIDs and have a "representation property" that uniquely matches the device for this to take effect. |
I still wonder if this is correct. The representation property was introduced to make sure the same device was not discovered twice with a different UID. Before that introduction, the match for equality was on UID. |
In theory yes. But know there are 20 different parameter UI classes with different presentation and update behaviour. Introducing an extra UI flag on each of them is, not only complex, but will also make the user experience worse. These parameter classes are not just used for the thing configuration parameters, they are used everywhere in the UI. Lastly, I think you need a mechanism to also control it with text based configurations. They are no different. Once the thing is loaded, configuration parameters still may get overwritten in memory. I don't think there is a check if the thing is managed before doing so. Of course, that check could be introduced in the code to avoid overwriting text defined things. That however breaks bindings that rely on some parameters to be discovered to work, even if you have defined the rest in a configuration file (some parameters cannot be known before discovery). |
The list is in fact longer, we have non-official bindings as well where some rely on these protocols. |
Of course, although I'd say that "rely on" is a strong term. If it's about IP addresses, this is just a problem for networks where devices as just assigned random IPs from the DHCP range. I have all devices on fixed IPs, as I would expect anybody that wants to have any control over their network to do, and as such, there is no desire or need for discovery to "mess with" the configuration.
I don't remember the exact source of this information at the moment, but I'm fairly sure that it's true. This is the code in question: As you can see, ThingUID is the very "criteria" being used to decide if "it's the same Thing". Also, these "dynamic updates" are only applied to managed Things, so there are a lot of Things out there that work just fine without this "feature" as well - or there would be a host of problems reported by users with file-based configurations.
It seems like it is. That said, I completely agree that there should be "functional parity" between managed and unmanaged here, and I must say that I consider the current implementation quite broken. It's a "hidden" feature that will help some and cause frustration for some, and it's quite random whether it "works" for you or not. As I've stated before, I think that it should ideally be handled by each binding that needs it. The next best option would be a per-Thing setting that the user controls, that is exposed/shown only for Things that utilize some of the discovery methods that does this. I'm just not sure if I see a way that can be implemented, an "injected configuration parameter" that is somehow done without the knowledge/participation of the binding itself. Maybe one of you can come up with something clever. Alternatively, there could be defined a "magic property" that is interpreted by core if it exists, and is used to determine if configuration parameters should be overwritten. Any bindings that want/needs to enable "dynamic" updates would then need to include this "magic property" as a configuration parameter, but wouldn't actually have to do anything with it, because core would evaluate it if it exists. |
I confirm. It looks like the representation property only hides new inbox entries that have the same representation property. But for an existing thing, only the thingID has an impact for updating the configuration parameters. So if you change it, it will not happen anymore. I find that a contradiction. Either you consider them the same, or you don't. |
I agree that it this becomes user controllable, it should work based on representation property, not ThingUID, I also think that it should be enabled for non-managed Things in that case. But, I'm still not sure that I see a way to handle making it configurable... |
Note: quick and dirty proof of concept; further refinement required; not tested..
Resolves #3753
This PR adds an xml configuration parameter attribute
dynamicto suppress the parameter from being dynamically updated by discovery services.Signed-off-by: Andrew Fiddian-Green software@whitebear.ch