I’ve noticed that it doesn’t really work to disable rules that are created using scripts (JavaScript, Python, Ruby etc.), so called “file-based” rules. You can disable them, but once you change the rule or restart OH, it’s back running.
I’ve also noticed that they generate rule UIDs that seem to be random (UUID like syntax), so I’m guessing that these are generated every time the script is run, resulting in a new rule UID each time, leaving a lot of “disabled phantom rule UIDs” in the JSONDB that don’t apply to the latest “iteration” of the rule.
My question is if this randomness has a good reason, or if it’s just a “convenience solution”. If it could be generated in some way that was deterministic, this whole problem could be avoided.
It this at all possible, or is it just one of those “live with it, it will never work” things?
I was able to reproduce the problem with file-based Python rules. I’m currently working on a fix within the Python helper libs by creating the UIDs myself.
I’m still puzzled as to why the Ruby rule that retained the UID still restarted… so maybe the check for “disabled” is somehow bypassed when rules are reloaded?
I checked the default behavior for my pythonscripting rules and after each reload they got a new random uid. Now, I provide “stable” uid and everything works. But its not 100% done and I have to leave. That’s why I will commit tomorrow
Creating a stable rule UID might not be so easy as it appears, duplicates must be avoided, which I assume is why randoms have been used in the first place.
Ideally, the file path (including filename) should probably be hashed somehow, and then some counter added for each rule in the file.
Even better, define the UID as something meaningful in the first place. As far as I know, all the languages support providing the IDs except Ruels DSL which uses the filename and position of the rule in the file (e.g. lighting_3 for the third rule defined in the file lighting.rules).
You are using SwitchableJSRule, not JSRule or rule builder. I think one of the primary things that does is ensure the same rule UID gets used every time the rule is loaded. When one doesn’t provide an ID though, the ID is randomly generated and therefore is different every time the file is loaded and the rule is recreated as @Nadahar reports.
That’s because when the file is changed, everything that was loaded/created from that file gets removed and then the file is loaded and creates the rules anew. And if you don’t supply your own rule UID, it will randomly generate one.
It seems likely that when the file is unloaded and the rule is removed, the entry of the disabled table also gets removed. So when the rule comes back it comes back as enabled since the disabled entry got removed.
@holger_hees , does Python not provide a way for the users to supply a UID of their choice? I’m not arguing against creating a stable random UID, but errors and such are so much easier to follow when it says “Rule weather_lights failed because …” compared to “Rule asdfwaerrqaxcb failed because …”, particularly when you can’t really search for asdfwaerrqaxcb in our actual files.
If it were up to me, I would make it so users must define an ID do away with all these randomized UIDs everywhere.
Or just use the same pattern as Rules DSL. At least the ID’s will be somewhat meaningful to the humans who have to deal with them.
This is of course the best solution, but I didn’t know if that’s always an option. It wouldn’t hurt if the generated UIDs were stable anyway though.
Yes, I said it to make testing quicker - there’s actually no need to restart OH is what I meant to say.
I considered that too, and checked the code in RuleEngineImpl that handles this, and can’t really find it. Maybe I’ve missed something, but it doesn’t really seem that disabled rule UIDs are ever removed from the “disabled registry” except for when a rule is explicitly enabled.
The only problem with using the filename is that you will get conflicts if rule files with the same name exists in different folders. Not all hashes are enourmous like UUIDs. I do agree that they aren’t exactly human-friendly, and it would be very nice with something more managable than what JS creates.
I don’t know about the other languages but the openHAB API supports the user supplying the UID when creating the rules so it’s theoretically possible. Whether all the languages expose it is a different question.
Rules DSL does not let you set the UID though. That is set at the filename and position of the rule in the file.
I’m willing to bet JS doesn’t create it at all and it’s using the UUID generator from OH core. I wouldn’t even be surprised if it’s all done in core. The UID is optional and something has to be used regardless of the language.
You can provide your own uid. If you are not providing a uid, it behaves like javascript. It will create a UID for you, based on “<rulename>-<uid>”. The only difference is that the generated UID is “stable”. It is a md5 hash, based on the file path.
Great, thank you. Even though those hashes are “ugly”, I think it’s the best solution. It doesn’t mean that people shouldn’t specify the UIDs, but if they don’t… you can still disable the rule.
To be clear, it may be that the rules have to have a name because the rules DSL requires it for some reason. Its probably a matter of backwards compatibility.
This name, however, it is entirely useless for debugging as it never shows up in the logs. There it is replaced by the above named numbering scheme.
I would recommend one if these things:
a) leave the name requirement and use that name in the logs , or
b) make the name optional or deprecated as it has no more functionality than a comment.
For both version I would love the name of the rule a preset const string that I can use in the logs just like receivedCommand or newState.
in that way, you have always a meaningful name which is used in logs and a unique uid which is needed in the rule registry. This means that in most scenarios, the user does not have to worry about names and uids at all
Every thing in OH has an ID which is usually restricted (e.g. no spaces, hay to be globally unique, etc) and a more human friendly name. Unfortunately for Items the UID is the called the “name” and the human friendly part is the label.
Rules are no different. It’s the name/label which is usually given promenence in the UIs but error messages often only report the UID because the names are not required to be unique.
The syntax for Rules DSL is far day older than using the filename-position for the UID.
But it’s not entirely useless for other things. Like I said, it’s the name that shows up more pomenently in the UIs. It’s users when searching in all the usual ways.
I would be against it’s removal. But I’m not too worried because there are not too many left who can change the Rules DSL syntax like that any more. Why do you think there are so many features in OH that Rules DSL simply can’t do.
For JS in the UI the rule ID is available as ruleUID but file based JS rules have filename.