Getting a part of a string in a rule

Hi all,

I’m trying to build an own alarm-system with openhab. My experience with openhab is not very extensive, so I’ve a simple question to rules. I’ve build a rule with the UI but my problem now is that my Nuki lock sends a state like this: 4,0,95763,0,1. For my rule I only need the first number. I’ve found some posts here ( [SOLVED] How to split a string in a rule ), but I’m not able to implement it to my own code. Can somebody help me please?

configuration: {}
triggers:
  - id: "1"
    configuration:
      event: ""
      thingUID: tapocontrol:T110:Tapo-Bridge:Alarm_Hub_Parterre:Open_Haustuer
      channelUID: tapocontrol:T110:Tapo-Bridge:Alarm_Hub_Parterre:Open_Haustuer:sensor#contactOpened
    type: core.ChannelEventTrigger
  - id: "3"
    configuration:
      itemName: Bass_Output_Switch
      command: ON
    type: core.ItemCommandTrigger
conditions:
  - inputs: {}
    id: "2"
    configuration:
      itemName: Haustuer_Schloss_actionevent
      operator: =
      state: "4"
    type: core.ItemStateCondition
actions:
  - inputs: {}
    id: "4"
    configuration:
      itemName: Stehlampe_Output_Switch
      command: OFF
    type: core.ItemCommandAction

In this example the state of id:2 Haustuer_Schloss_actionevent is what I need. I need a state 4, but I get 4,0,95763,0,1. I think I can get the first part with the following command

Haustuer_Schloss_actionevent.split(’ , ').get(0)”

but can I create a variable and an if-function at the conditions part?

Thanks for your help in advance

Michael

Hello @gandalf23

This would require creating a script in the rule that can be created when you click add action

You will need to pick the language you want to use (all except DSL which is more legacy) are good choices with the first Blockly being a good choice for beginners and for those not familiar with coding or the other languages because it provides a drag and drop approach. Rules Blockly | openHAB

blockly is also a good choice because it will allow you to see the code that it has generated

To use Blockly you will also need to have the Javascript addon installed in openHAB JavaScript Scripting - Automation | openHAB

1 Like

Hi,

You can already do the splitting with a transformation in the profile (between item and channel). If you have to change “SCRIPT Rule DSL (v1)” to “Thing to Item Transformation”
| input.split(',').get(0);

2 Likes

Thank you for your answer @BrettLHolmes,

I’ve tried it with javascript, without Blockly, but I don’t know how my core.ItemStateCondition does now the variable from the script part. The variable is not defined global. How do I define it global, if I only can use scripting in a single function?

Perhaps I have an error in my (thinking) logic, but from programming languages I now a little bit, a variable defined in an function is only local to this function.

Sorry for my stupid questions, but I try understand how it works with rules.

Here is my new code:

configuration: {}
triggers:
  - id: "1"
    configuration:
      event: ""
      thingUID: tapocontrol:T110:Tapo-Bridge:Alarm_Hub_Parterre:Open_Haustuer
      channelUID: tapocontrol:T110:Tapo-Bridge:Alarm_Hub_Parterre:Open_Haustuer:sensor#contactOpened
    type: core.ChannelEventTrigger
  - id: "3"
    configuration:
      itemName: Bass_Output_Switch
      command: ON
    type: core.ItemCommandTrigger
conditions:
  - inputs: {}
    id: "2"
    configuration:
      itemName: Haustuer_Schloss_actionevent
      operator: =
      state: lock_staus
    type: core.ItemStateCondition
  - inputs: {}
    id: "4"
    configuration:
      type: application/javascript
      script: |-
        var lock_status = 9;
        if (Haustuer_Schloss_actionevent.split(',')[0]=4){
        lock_status=4;
        }
    type: script.ScriptCondition
actions:
  - inputs: {}
    id: "5"
    configuration:
      itemName: Stehlampe_Output_Switch
      command: OFF
    type: core.ItemCommandAction



Thanks in advance

Thanks for your answer too, I think I’ve to look for transformations at the future, but at the moment I have no idea about the things you are writing.

Sorry

There are a couple of important concepts here:

  1. When defining a rule using the UI you can only add scripts or script-like functions to specific script elements (such as the inline script action). All other values are static.

  2. All of the different components of the rule that do include lines of script (either script actions or script conditions) run in their own context. It is possible to use the shared cache to set values that can be accessed by multiple scripts, but that, again, is only available between scripts, it is not something you can access in the other UI configured rule parts like a Item action.

  3. Conditions are evaluated only to determine if the rules actions should be run. Not to pass values to other parts of the rule. If a condition is a script, then the rules engine will run that script and wait for it to return a value that is either true or false. If the value is true the then the rule execution continues (either to the next condition or to the first action), if it is false then the rule execution halts at that point and no further actions are taken.

With those things in mind you have two options here:

  1. You can process the incoming value of your lock before the rule ever begins to run and then have a simple rule built completely in the UI with a condition that checks the single already processed value of the lock. There are numerous ways to transform the value depending on the binding/channel your item is linked to, but this what a transform profile could do for you.
  1. If you are going to keep the full 4,0,95763,0,1 state of the lock then you will have to do most of the work of the rule in the script action and not bother with a separate condition. In this case you would still have the same rule triggers you have configured, but then you will just have a single inline script action. Then within that script you will:
  • Extract the value you need from the lock’s state
  • Test that value
  • Send a command or not to the target item based on the result of the test.

Any of the available scripting languages can handle this basic script.

1 Like

javascript:

let rfinput = "4,0,95763,0,1"
rfinput = rfinput.slice(0,1)
  console.info(rfinput)

Don’t know if that is what you want but it works.

1 Like

Did you work it out?
If so how?

Hi @JustinG,

sorry for my late answer and thanks for your detailed explanation, that helps a lot. I will try with scripting and come back here.

sorry, not yet.