Search for an item name in rules

Hi,

Is there a way to easily find where a given item is used in the rules (all) ? It was easy to do it with OpenHAB 2.x since the rules were stored in a file. I did not see how to do the same with OpenHAB 3.x when the rules are stored in the database (automation_rules.json). I can of course do a search in this database but it is not as convenient as it was
with OpenHAB 2.x.

This is useful when you have to replace as for instance an old switch with a new one and that switch is used in several rules.

Thanks in advance,

1 Like

See OH 3 Tips and Tricks but the tl;dr is no, you’ll need to search through the JSONDB file and, potentially change it there (though it’ll be better not to edit the file if you can help it).

Thanks for the tips and tricks. It would be a nice feature to have the possibility to search not only for a given rule through the web ui but also the items used by the rules (a tick box close to the search field ?). I use sometimes a tablet to make some small modifications to my openhab config and it is not very convenient to log in to my NAS to look into a file at the same time. Anyway, the transfer from 2.5 to 3.0 is now completed successfully. I like very much 3.0 !

I installed a program called jq on my Linux OS and I run this command:
cat /var/lib/openhab/jsondb/automation_rules.json | jq . |less

It gives output like below and I search for the item or whatever.

44f53af813”: {
“class”: “org.openhab.core.automation.dto.RuleDTO”,
“value”: {
“triggers”: [
{
“id”: “1”,
“configuration”: {
“itemName”: “LightHall_LightHall”,
“state”: “ON”,
“previousState”: “OFF”
},
“type”: “core.ItemStateChangeTrigger”
}
],

In the above example the 44f53af813 is the rule id and I just use ctrl-f to search on the web page and ctrl-v to paste the 44f53af813 into the search to fine the rule.

Thanks to provide me this idea. jq is available on my NAS (Synology). I will see how I can expose this through a web page instead of a command line. I am also studying the API Explorer but not sure I can get a list of all uid rules to iterate over.

Thanks again

And yes, the API can provide the list of all uids ! So it will thus make possible to iterate over all the rules and search for a particular item name. I just need to make available of web page for that !

That would be handy in a web page. If you very it working let us know.
You could make it search the other json files as well.

I am doing little progress on that (I lost my programming skills by doing too much management…).

But I have the scenario: I did a page layout with an oh-input card to enter the item name to search into the rules definitions. When validating the input, a rule is activated to send a request via the REST API (http://xxx.xxx.x.xx:8080/rest/rules). Then the JSON result has to be processed. I only need to think about the final step: displaying the list of rules where the item is used in the same page layout… I did not yet found the widget to do it.

It is unbelievable what OH3 can do… amazing !

I wrote a script to test if I can get access to the script associated with a rule (8e5cd6e905 in my set of rules).
Using jq, I can get access to the script using the following command:

/usr/bin/jq ‘.“8e5cd6e905”.value.actions | .[] | .configuration.script’ automation_rules.json

I was forced to use “” with the uid to make it to work.

I tried to do it within a script:

var String uidtest = "\"8e5cd6e905\"" + ".value.actions | .[] | .configuration.script"
var String jqresult_script = executeCommandLine(Duration.ofSeconds(1),"/usr/bin/jq", uidtest, "/openhab/userdata/jsondb/automation_rules.json")

Unfortunately, I got the following error:

2021-03-19 10:59:08.337 [INFO ] [org.openhab.core.model.script.exec ] - jq: error (at /openhab/userdata/jsondb/automation_rules.json:1532): Cannot index string with string "value"

Do you have any idea why I got this error ?

If I solve this issue then the following script can iterate over the set rules:

var String jqresult_uid = executeCommandLine(Duration.ofSeconds(1), "/usr/bin/jq", ".[] | .value.uid", "/openhab/userdata/jsondb/automation_rules.json")
var String listuid = jqresult_uid.replace('"\n', ',').replace('"','')
val arrayuid = listuid.split(',')
// iterate over the list of rules - just display the uid in the log
arrayuid.forEach[ num | logInfo("exec", "" + num + "") ]

Thanks in advance

Looks like you’ve got space characters in the string you are passing to exec.

It seems to be the use of double quote (\") with the uid that raises the issue. if I use the following command using the shell:

/usr/bin/jq '."8e5cd6e905".value.actions|.[]|.configuration.script' automation_rules.json

It works fine. Without the double quote:

/usr/bin/jq '.8e5cd6e905.value.actions|.[]|.configuration.script'  automation_rules.json
jq: error: syntax error, unexpected IDENT, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
.8e5cd6e905.value.actions|.[]|.configuration.script    
jq: 1 compile error

Thus is why I used \" in uidtest string.

Problem is solved using a different approach:

var String uidtest = ".[] | select(.value.uid == \"7f685724fe\") | .value.actions | .[] | .configuration.script"
var String jqresult_script = executeCommandLine(Duration.ofSeconds(1),"/usr/bin/jq", uidtest, "/openhab/userdata/jsondb/automation_rules.json")

It works perfectly well to extract the script of a the rule with the uid=7f685724fe

Herewith a proof of concept to look for a particular item into the rules scripts. More work has to be done to show the list of rules in a nicer way in the page layout. I tried to be as minimalist as possible (using only OH3 to implement this search feature). I tried first to use the JsonPath Transformation Service but I did not succeed to extract the required information. I thus used jq instead (you need thus to install jq).

Do not blame me on the quality of the code, I lost my programming skills…:slight_smile:

Two String items:

LookForAnItemName : the name of the item to search into the rules scripts
ListOfRules: a list of rules uid in which the item was found

A single rule:

triggers:
  - id: "1"
    configuration:
      itemName: LookForAnItemName
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/vnd.openhab.dsl.rule
      script: >
        logInfo("notifications", "Looking for an item name in all script
        associated with the rules (itemname=" + LookForAnItemName.state + ")")

        var String jqresult_uid = executeCommandLine(Duration.ofSeconds(1), "/usr/bin/jq", ".[] | .value.uid", "/openhab/userdata/jsondb/automation_rules.json")

        var String listuid = jqresult_uid.replace('"\n', ',').replace('"','')

        val arrayuid = listuid.split(',')

        // init the item

        ListOfRules.sendCommand("")

        // iterate over the list of rules

        arrayuid.forEach[ num | 
                         var String uidtest = ".[] | select(.value.uid == " + "\"" + num + "\"" +") | .value.actions | .[] | .configuration.script"
                         var String jqresult_script = executeCommandLine(Duration.ofSeconds(1),"/usr/bin/jq", uidtest, "/openhab/userdata/jsondb/automation_rules.json")
                         if (jqresult_script.contains(LookForAnItemName.state.toString())) {
                           var String PrevRules = ListOfRules.state.toString()
                           ListOfRules.sendCommand(PrevRules + num + ",")                   
                         }
                        ]
        logInfo("notifications", ListOfRules.state.toString())
    type: script.ScriptAction

And the following page layout:

config:
  label: SearchItem Layout
  sidebar: true
blocks: null
masonry:
  - component: oh-masonry
    slots:
      default:
        - component: oh-input-card
          config:
            outline: true
            inputmode: text
            footer: = items.ListOfRules
            title: Search item
            type: text
            sendButton: true
            validate: false
            item: LookForAnItemName
            clearButton: true